质因数 【欧拉线筛变形】

本人水平有限,题解不到为处,请多多谅解

本蒟蒻谢谢大家观看

 不清楚线筛的点这里传送门

题目:

质因数

(prime.cpp/in/out 1s 128M)

OtosakaYuu最近为了Nao Tomori拯救世界而立了一个flag,于是他想了一道数学题。有一个正整数数列a1,a2an。定义函数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
",prime[a[i]]);
37     }
38     return 0;
39 }
原文地址:https://www.cnblogs.com/nlyzl/p/11714166.html