简体   繁体   中英

Calculating the number of prime factors

The following was the problem on codeforce
Two soldiers are playing a game. At the beginning first of them chooses a positive integer n and gives it to the second soldier. Then the second one tries to make maximum possible number of rounds. Each round consists of choosing a positive integer x > 1, such that n is divisible by x and replacing n with n / x. When n becomes equal to 1 and there is no more possible valid moves the game is over and the score of the second soldier is equal to the number of rounds he performed.

To make the game more interesting, first soldier chooses n of form a! / b! for some positive integer a and b (a ≥ b). Here by k! we denote the factorial of k that is defined as a product of all positive integers not large than k.

What is the maximum possible score of the second soldier?

Input First line of input consists of single integer t (1 ≤ t ≤ 1 000 000) denoting number of games soldiers play.

Then follow t lines, each contains pair of integers a and b (1 ≤ b ≤ a ≤ 5 000 000) defining the value of n for a game.

Output For each game output a maximum score that the second soldier can get.

So i tried to calculate the number of prime factors of n(as in the prime factorization of n).
Following is my my code but it fails for the test case
a=5000000 and b= 4999995

import java.util.Scanner;
import java.lang.*;

public class Main {

public static void main (String[] args) throws java.lang.Exception
{
    // your code goes here
    int count=0;

    Scanner input=new Scanner(System.in);

    int testcases=input.nextInt();

    for(int m=1;m<=testcases;m++){
        count=0;
        long a=input.nextLong();
        long b=input.nextLong();
        double n=1;

            for(double i=b+1;i<a+1;i++)
                n=n*i;
        //System.out.println(Math.sqrt(n));

            for(int i=2;i<Math.sqrt(n);i++){

                    if(n%i==0){
                        while(n%i==0){
                            n=n/i;

                            count++;
                        }
                    }   
            }

            if(n!=1) count++;

            System.out.println(count);  
    }
  } 
}

In your case, a! / b! is

3,124,993,750,004,374,998,750,000,120,000,000

which is somewhat larger than 2^111. Only numbers up to 2^53 can be safely represented as an integer with a double value. If you use long , you can crank that up to 2^63, which still isn't enough.

You must either use BigInteger or you must change your approach: Instead of dividing the result of a! / b! into prime factors, divide the factors that contribute to the factorial and then merge the prime factor sets.

To illustrate with your example:

5000000 == 2^6 * 5^7
4999999 == 4999999
4999998 == 2 * 3 * 191 * 4363
4999997 == 43 * 116279
4999996 == 2^2 * 1249999

a! / b! == 2^9 * 3 * 5^7 * 43 * 191 * 4363 * 116279 * 1249999 * 4999999

As the input for a and b is small, we can create an array numOfPrime , which at index ith,

numOfPrime[i] = number of prime factor of i

So, we notice that numOfPrime[i] = 1 + numOfPrime[i/x] with x is any prime factor of i.

For simplicity, let x be the smallest prime factor of i , we can use Sieve of Eratosthenes to precalculate x for each i

int[]x = new int[5000001];
for(int i = 2; i < x.length; i++)
    if(x[i] == 0)
       for(int j = i + i; j < x.length; j+= i)
           if(x[j] == 0)
              x[j] = i;

int[]numOfPrime = new int[5000001];

for(int i = 2; i < x.length; i++)
    if(x[i] == 0)
       numOfPrime[i] = 1;
    else
       numOfPrime[i] = 1 + numOfPrime[i/x[i]];

You can take a look at my submission for this problem

Based on @m-oehm's answer:

int[] factors = new int[a-b];
for(int i=0;i<a-b;i++)
   factors[i] = b+1+i;

boolean done = false;
int i = 2;
while(!done){
   done = true;
   for(int j=0; j<a-b; j++){
      if(i>Math.sqrt(factors[j]) && factors[j]!=1){  // factors[j] is prime
         factors[j] = 1;
         count++;
      }else{
         while(factors[j]%i==0){   // divide factors[j] by i as many times as you can
            factors[j]/=i;
            count++;
         }
      }
      if(factors[j]!=1)            // if all factors have reach 1, you're done
         done = false;
   }
   i++;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM