[英]Need help calculating the amount of different prime factors of every number up to a given number
[英]Calculating the number of prime factors
以下是Codeforce上的問題
兩名士兵在玩游戲。 首先,他們選擇一個正整數n並將其提供給第二個士兵。 然后第二個嘗試使最大回合數成為可能。 每個回合包括選擇一個正整數x> 1,這樣n可以被x整除並用n / x替換n。 當n等於1並且沒有更多可能的有效動作時,游戲結束,第二名士兵的得分等於他執行的回合數。
為了使游戲更有趣,第一個士兵選擇形式a的n! / b! 對於一些正整數a和b(a≥b)。 在這里乘k! 我們表示k的階乘定義為所有不大於k的正整數的乘積。
第二個士兵的最大可能分數是多少?
輸入輸入的第一行包含一個整數t(1≤t≤1 000 000),表示士兵玩的游戲次數。
然后跟隨t行,每行包含一對整數a和b(1≤b≤a≤5 000 000),這些整數定義了游戲的n值。
輸出對於每個游戲,輸出第二個士兵可獲得的最大分數。
所以我試圖計算n的素因數(如n的素因數分解)。
以下是我的代碼,但在測試用例中失敗
a = 5000000和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);
}
}
}
在您的情況下,一個! / b! 是
3,124,993,750,004,374,998,750,000,120,000,000
比2 ^ 111大一點。 只有最大2 ^ 53的數字才能安全地表示為帶double
值的整數。 如果使用long
,則可以將其提高到2 ^ 63,但這還不夠。
您必須使用BigInteger
或必須更改方法:而不是除a的結果! / b! 分解為主要因子,將有助於析因的因子進行划分,然后合並主要因子集。
為了說明您的示例:
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
由於a
和b
的輸入很小,我們可以創建一個數組numOfPrime
,該數組的索引為ith,
numOfPrime[i] = number of prime factor of i
因此,我們注意到帶有x
numOfPrime[i] = 1 + numOfPrime[i/x]
是i的任意素數。
為簡單起見,讓x
為i
的最小素數,我們可以使用Eratosthenes篩子為每個i
預先計算x
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]];
您可以看看我針對此問題提交的內容
基於@ m-oehm的答案:
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++;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.