One Point Solution

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Saturday, 3 March 2012

SRM 535 : lame

Posted on 12:29 by Unknown
The other day I decided to stop opening the medium problem first. So to open div1 500 once warmed up as opposed to 250. I think this will hurt my rating, as you can see from today's performance in which I picked a unnecessarily long solution for it. Coded it with a lot of unnecessarily steps and took a lot of time to fix many bugs. The result was a very slow submission and low score. I felt the difference when I opened the medium though because I was more active then. I have to improve my pace so that my activity level is high the whole match, but it is going to be hard.

Div 1 250: FoxAndGCDLCM
You get two numbers: L and G, both between 1 and 10^12, inclusive. Find two numbers A and B such that gcd(A,B) = G, lcm(A,B) = L and (A+B) is as small as possible.

This is the approach I took during the match: The number of distinct prime factors for a number less than 10^12 is very low (Remembering last match, this number is definitely less than 15). We can extract prime factors of a number N in O(sqrt(N)) time. So, imagine we extracted the distinct prime factors of G and L, since by definition L is a multiple of G, then G will never have a prime factor that is not a prime factor of L. (If L is not a multiple of G, return -1 instantly). In fact, since we are talking about distinct prime factors, you also need, for each distinct factor, the number of times it appears as a factor of G and L. (For example, for G=40, the factorization is 2*2*2*5, 2 appears three times and 5 one time). Note that A and B both have to be multiples of G. This means that they both have to be multiples of each of the prime factors of G raised to the number of times the factor appears in G. The number of times a factor appears in L will be greater than or equal to the number of times it appears in G. This means that the minimum number of times a factor appears in A or B is equal to the number of times it appears in G. Similarly, the maximum number of times the factor appears in A or B is equal to the number of times it appears in L. Note that a factor cannot appear a number of times different to the minimum or the maximum (else the lcm rule wouldn't work). More so, if a factor appears the minimum number of times in A, it must appear the maximum number of times in B and viceversa.

So we have less than 15 prime factors and a decision, for each of them to place in A or B. You can just try all different 215 ways to make these decisions. For each of them, calculate A and B, then pick the minimum A+B possible.

//Death to long! 
typedef long long int64;
#define long int64
#define var(q,s) typeof(s) q = s
#define for_each(q, s) for( var(q,s.begin()); q!=s.end(); q++)
struct FoxAndGCDLCM
{
//Extract each prime factor,
// and the number of times it appears in x:
map<long, int> factorize(long x)
{
var(p, 2ll);
map<long, int> res;
//no need to check for a factor larger than sqrt(p)
while (p <= x / p) {
while (x % p == 0) {
res[p]++;
x /= p;
}
p ++;
}
if (x != 1) {
res[x]++;
}
return res;
}


long get(long G, long L)
{
if (L % G != 0) {
return -1;
}
var( gfactors, factorize(G));
var( lfactors, factorize(L));

pair<int, long> res = make_pair(1, -1ll);
//t different prime factors.
int t = lfactors.size();
// try each possible combination of decisions.
// 2^t in total (same as saying 1<<t).
for (int mask=0; mask<(1<<t); mask++) {
long A = G, B = G;
int i = 0; //so we know the index of the prime factor.
for_each(q, lfactors) {
long p = 1;
for (int j=gfactors[q->first]; j < q->second; j++) {
p *= q->first;
}
//decide...
if (mask & (1<<i)) {
A *= p;
} else {
B *= p;
}
i++;
}
res =std::min(res, make_pair(0, A+B) );
}
return res.second;


}
};
#undef long




That's the code I wish I coded, compare it with this monstrousity if you wish...

Now, that solution is still quite lame. Compare it with this one: L must be a multiple of G. Ok, now consider that A and B must be multiples of G. But what if we set a = A / G and b = B / G. Then a*b would hold all the factors that are not common to A nor B. a*b is also equal to L/G (try L = A*B / G as a base). Also notice that A+B = a*G + b*G = G * (a+b) and thus minimizing a*b yields the answer. Then since a*b are factors of L/G, you can just try all pairs (a,b) of numbers such that a*b = L/G (ie: extract the divisors of L/G in O(sqrt(L/G)). However, make sure the pairs (a,b) are coprime (again, else the lcm rule wouldn't hold). Notice that these two solutions do exactly the same thing... But the new solution looks like this:

//Death to long! 
typedef long long int64;
#define long int64

//Euclid's GCD
template<class T> T gcd(T a, T b)
{
while (b != 0) {
T c = b;
b = a % b;
a = c;
}
return a;
}

struct FoxAndGCDLCM
{
long get(long G, long L)
{
if (L % G != 0) {
return -1;
}
pair<int, long> res = make_pair(1, -1);
long ab = L/G;
// divisors of ab
for(long a=2; a <= ab/a; a++) {
if (ab % a == 0) {
//try all pairs (a,b)
long b = ab / a;
if (gcd(a,b) == 1) { //pair-wise coprime?
res = std::min(res, make_pair(0, (a + b)*G ) );
}
}
}
return res.second;
}
};
#undef long



Challenge phase et all
I had some ideas for div1 500, nothing concrete I think I will post something later. I avoid any challenge during the challenge phase.

Opinions?
The problems I opened seemed good. Div1 250 was fun. I was just too slow.
Email ThisBlogThis!Share to XShare to Facebook
Posted in badday, srm, topcoder | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • TopCoder SRM 557 - finally
    SRM 557 Explanation for division 1 Easy and match recap. Explanations for div2 easy and div2 medium. It feels like it has been ages since t...
  • SRM 589 Editorial
    I have finished writing the editorial for TopCoder SRM 589: http://apps.topcoder.com/wiki/display/tc/SRM+589 . As you most likely noticed. L...
  • SRM 590 recap and editorial
    Another week another Topcoder match. Not a great day. I had a bad flu and still do. Div1 500: The one with Xor Given a list of cards with nu...
  • SRM 546: relief
    I figured I should post something about this SRM. I've been very busy these weeks because the semester is ending and I tried to win a t-...
  • SRM 526: The killing wait for results
    While I wait for results, here is my perspective on this algorithm contest. It began with issues, it had to be postponed 15 minutes. TC has ...
  • SRM 554 div1 hard: TheBrickTowerHardDivOne
    Link to problem statement We got infinitely many bricks of dimensions 1x1x1 and C different colors. Count the number of towers of size 2x2...
  • SRM 533: Div1 500 MagicBoard explanation
    Finally solved it. It is a nice problem that is worth explaining in a post. You have a grid/board of at most 50x50 cells. Some cells contain...
  • Member SRM 505: Part 1
    So, let me explain a couple of problems from a Topcoder Member SRM that I wrote and never got an editorial. BTW, it was the last member SRM....
  • ListedLinks 2012-02-10
    Saturday Morning Breakfast Cereal comics: Grace Hopper's ghost That Oracle engineer blog post Oracle would really not like anyone to se...
  • Codeforces "Good bye 2013" round
    So it was a special round for coders of both divisions, problems ranged from the super easy problem A to the super difficult problems E,F,G....

Categories

  • acm
  • algorithm
  • answers
  • arenaplugin
  • badday
  • behindthescenes
  • bugs
  • c++
  • censorship
  • codechef
  • codeforces
  • contests
  • crocchamp
  • editorial
  • editorial.srm
  • embarrassing
  • explanation
  • gcj2013
  • gmp
  • goodday
  • google
  • googlecodejam
  • greed
  • groklaw
  • health
  • html
  • httpseverywhere
  • implementation
  • ipsc
  • ispc
  • java
  • kawigiedit
  • kindagoodday
  • lamebook
  • languages
  • lego
  • listedlinks
  • marathon
  • nasa
  • offtopic
  • ouch
  • postmortem
  • postportem
  • practical
  • probably_not_a_good_tip
  • problemsetting
  • programming
  • python
  • quora
  • rant
  • recap
  • slightlygoodday
  • snippet
  • srm
  • stl
  • strategy
  • swerc
  • tco
  • tco12
  • tco13
  • tco2012
  • tco2013
  • ternarysearch
  • topcoder
  • tricks
  • ubuntu
  • uva
  • vjass
  • vkcup
  • wc3
  • zinc

Blog Archive

  • ►  2014 (1)
    • ►  January (1)
  • ►  2013 (141)
    • ►  December (14)
    • ►  November (8)
    • ►  October (13)
    • ►  September (11)
    • ►  August (14)
    • ►  July (15)
    • ►  June (13)
    • ►  May (13)
    • ►  April (12)
    • ►  March (11)
    • ►  February (11)
    • ►  January (6)
  • ▼  2012 (94)
    • ►  December (5)
    • ►  October (6)
    • ►  September (8)
    • ►  August (6)
    • ►  July (3)
    • ►  June (5)
    • ►  May (8)
    • ►  April (10)
    • ▼  March (20)
      • Topcoder Open 2012 round 1A
      • Codeforces round #114. 167C: Wizards and numbers
      • Official TCO 2012 blogger
      • Codeforces round #114 (div1)
      • 5 reasons editorial votes in Topcoder are useless
      • Codeforces VK Cup round 2: (ouch)
      • Codeforces round #113 div2 (unofficial)
      • Writing SRM 538
      • SRM 537: oh my
      • Codeforces round #112
      • Language features: Rants and wishes
      • Google code jam registration - Just note something...
      • Codeforces: VK Cup round 1: Problem C: Abracadabra
      • Codeforces: VK Cup round 1 (update 1)
      • SRM 536: heh
      • SRM 535 editorial: The making of
      • Codeforces round #111 (div2 only)
      • SRM 535 : lame
      • A note about SRM 537 and 540 money prizes
      • The March of Destruction begins!
    • ►  February (16)
    • ►  January (7)
  • ►  2011 (51)
    • ►  December (7)
    • ►  November (12)
    • ►  October (5)
    • ►  September (1)
    • ►  August (3)
    • ►  July (4)
    • ►  June (3)
    • ►  May (7)
    • ►  April (3)
    • ►  March (2)
    • ►  February (1)
    • ►  January (3)
  • ►  2010 (9)
    • ►  December (4)
    • ►  October (1)
    • ►  June (1)
    • ►  May (1)
    • ►  January (2)
  • ►  2009 (1)
    • ►  December (1)
Powered by Blogger.

About Me

Unknown
View my complete profile