质因数 【欧拉线筛变形】
本人水平有限,题解不到为处,请多多谅解
本蒟蒻谢谢大家观看
不清楚线筛的点这里:传送门
题目:
质因数
(prime.cpp/in/out 1s 128M)
OtosakaYuu最近为了Nao Tomori拯救世界而立了一个flag,于是他想了一道数学题。有一个正整数数列a1,a2…an。定义函数f(x)为x的不同的质因数数量。球f(a1),f(a2)…f(an)。
Input
第一行包含一个正整数,表示n。
接下来n行,每行包含一个正整数ai。
1<=n<=1000000,2<=ai<=1000000
Output
输出n行,第i行输出f(ai)。
Sample Input
3
12
30030
2333
Sample Output
2
6
1
【样例说明】
12=2×2×3;
30030=2×3×5×7×11×13;
2333是一个质数。
线筛的简单变形
我们要先预处理,因为数据范围太大
1:
for(int j=i;j<=maxn;j+=i){//枚举约数 prime[j]++;
}
2:
for(int j=i;j<=maxn/i;j++){//判断约数是否为质因数 inprime[i*j]=0;
}
prime[]代表的是当前数字的质约数个数,因为是预处理,所以不会出现重复约数情况
inprime[]代表的是是否为质数,先初始所有都不是质数,如果是质数就标记为false
code:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e6+15; 4 int n; 5 int prime[maxn],inprime[maxn],a[maxn]; 6 inline int read(){ 7 int x=0,f=1;char ch=getchar(); 8 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 9 while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 10 return x*f; 11 } 12 void work(){ 13 memset(inprime,1,sizeof(inprime)); 14 for(int i=2;i<=maxn;i++){ 15 if(inprime[i]){ 16 for(int j=i;j<=maxn;j+=i){//枚举约数 17 prime[j]++; 18 // cout<<"j11111= "<<j<<" i1111= "<<i<<endl; 19 //cout<<"prime[j]= "<<prime[j]<<" j= "<<j<<" i= "<<i<<endl; 20 } 21 for(int j=i;j<=maxn/i;j++){//判断约数是否为质因数 22 inprime[i*j]=0; 23 //cout<<"j2222= "<<j<<" i2222= "<<i<<endl; 24 } 25 } 26 } 27 } 28 int main() 29 { 30 n=read(); 31 for(int i=1;i<=n;i++){ 32 a[i]=read(); 33 } 34 work(); 35 for(int i=1;i<=n;i++){ 36 printf("%d\n",prime[a[i]]); 37 } 38 return 0; 39 }