(This is derived from a recently completed programming competition)
You are given two arrays of 10^5 ints in the range 1..10^7 inclusive:
int N[100000] = { ... }
int D[100000] = { ... }
Imagine the rational number X be the result of multiplying together all the elements of N and dividing by all the elements of D.
Modify the two arrays without changing the value of X (and without assigning any element out of range) such that the product of N and the product of D have no common factor.
A naive solution (I think) would work would be…
for (int i = 0; i < 100000; i++)
for (int j = 0; j < 100000; j++)
{
int k = gcd(N[i], D[j]); // euclids algorithm
N[i] /= k;
D[j] /= k;
}
…but this is too slow.
What is a solution that takes less than around 10^9 operations?
Factorise all numbers in the range 1 to 107.
Using a modification of a Sieve of Eratosthenes, you can factorise all numbers from 1 toBetter than that is probably creating an array of just the smallest prime factors.ninO(n*log n)time (I think it’s a bit better,O(n*(log log n)²)or so) usingO(n*log log n)space.To factorise a number
n > 1using that sieve, look up its smallest prime factorp, determine its multiplicity in the factorisation ofn(either by looking up recursively, or by simply dividing untilpdoesn’t evenly divide the remaining cofactor, which is faster depends) and the cofactor. While the cofactor is larger than 1, look up the next prime factor and repeat.Create a map from primes to integers
Go through both arrays, for each number in
N, add the exponent of each prime in its factorisation to the value in the map, for the numbers inD, subtract.Go through the map, if the exponent of the prime is positive, enter
p^exponentto the arrayN(you may need to split that across several indices if the exponent is too large, and for small values, combine several primes into one entry – there are 664579 primes less than 107, so the 100,000 slots in the arrays may not be enough to store each appearing prime with the correct power), if the exponent is negative, do the same with theDarray, if it’s 0, ignore that prime.Any unused slots in
NorDare then set to 1.