素数相関アルゴリズム
8207 ワード
1.素性テスト
//素性テストo(sqrt(n))
//約数列挙o(sqrt(n))
//整数分解o(sqrt(n))
2.オングスクリーン法o(nlogn)
3.区間ふるい法
//素性テストo(sqrt(n))
1 int is_prime(int n)
2 {
3 for(int i=2;i*i<=n;i++){
4 if(n%i==0) return 0;
5 }
6 return n!=1;
7 }
//約数列挙o(sqrt(n))
1 vector<int> divisor(int n) {
2 vector<int> res;
3 for(int i=2;i*i<=n;i++) {
4 if(n%i==0) {
5 res.push_back(i);
6 if(i!=n/i) res.push_back(n/i);
7 }
8 }
9
10 return res;
11 }
//整数分解o(sqrt(n))
1 map<int,int> prime_factor(int n)
2 {
3 map<int,int> res;
4 for(int i=2;i*i<=n;i++) {
5 while(n%i==0) {
6 res[i]++;
7 n/=i;
8 }
9 }
10 if(n!=1) res[n]=1;
11 return res;
12 }
2.オングスクリーン法o(nlogn)
1 int sieve(int n)
2 {
3 int p=0;
4 clr(is_prime,0);
5 is_prime[0]=is_prime[1]=1;
6
7 for(int i=2;i<=n;i++) {
8 if(!is_prime[i]) {
9 prime[++p]=i;
10 for(int j=2*i;j<=n;j+=i) is_prime[j]=1;
11 }
12 }
13 return p;
14 }
3.区間ふるい法
1 void segment_sieve(LL a,LL b)
2 {
3 for(int i=0;(LL)i*i<b;i++) is_prime_small[i]=true;
4 for(int i=0;i<b-a;i++) is_prime[i]=true;
5
6 for(int i=2;(LL)i*i<b;i++) {
7 if(is_prime_small[i]) {
8 for(int j=2*i;(LL)j*j<b;j+=i) is_prime_small[j]=false;
9 for(LL j=max(2LL,(a+i-1)/i)*i;j<b;j+=i) is_prime[j-a]=false;
10 }
11 }
12
13 }