zoukankan      html  css  js  c++  java
  • 素数的线性筛 && 欧拉函数

    O(n) 筛选素数

    #include<bits/stdc++.h>
    using namespace std;
    const int M = 1e6 + 10 ;
    
    int mindiv[M] ;//每个数的最小质因数
    int prim[M] , pnum ;//存素数
    bool vis[M] ;
    
    void prim () {
            for (int i = 2 ; i < M ; i ++) {
                    if (!vis[i]) {
                            mindiv[i] = i ;
                            prim[ pnum++ ] = i ;
                    }
                    for (int j = 0 ; j < pnum ; j ++) {
                            if ( i*prim[j] >= M ) break ;
                            vis[ i*prim[j] ] = 1 ;
                            mindiv[i] = prim[j] ;
                            if (i % prim[j] == 0) break ;
                    }
            }
    }
    
    int main () {
            prim () ;
            return 0 ;
    }
    

      欧拉函数:phi[i] 为<= i 的范围内与i互质的数的数量

      欧拉埃筛,写起来简单,复杂度O(log(log(N)))(zstu 幻神):

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int M = 1e6 + 10 ;
    
    int n, m, T;
    
    int euler[M];
    
    void Euler () {
            for(int i = 0; i < M ; i ++) euler[i] = i;
            for(int i = 2; i < M ; i ++){
                    if(euler[i] == i) {
                            for (int j = i; j < M ; j += i) {
                                    euler[j] = euler[j] - euler[j]/i;
                            }
                    }
            }
    }
    
    int main(){
            Euler ();
            int n ;
            while (~ scanf ("%d" , &n)) printf ("%d
    " , euler[n]) ;
            return 0;
    }
    

      

    欧拉线筛,写起来复杂点,(墨迹了我半天)复杂度O(N):

    #include<bits/stdc++.h>
    using namespace std;
    const int M = 1e6 + 10 ;
    int prim[M] , pnum ;
    bool vis[M] ;
    int phi[M] ;
    
    void Euler () {
            for (int i = 2 ; i < M ; i ++) {
                    if (!vis[i])  {
                            prim[ pnum++ ] = i ;
                            phi[i] = i - 1;
                    }
                    for (int j = 0 ; j < pnum ; j ++) {
                            int x = i * prim[j] ;
                            if (x >= M ) break ;
                            vis[x] = 1 ;
                            if (i % prim[j] == 0) {
                                    int y = i , cnt = 0 , z = prim[j] ;
                                    while (y % prim[j] == 0) cnt ++ , y /= prim[j] , z *= prim[j] ;
                                    if (y == 1) phi[x] = x - x/prim[j] ;
                                    else phi[x] = phi[y] * phi[z] ;
                                    break ;
                            }
                            else phi[x] = phi[i] * phi[ prim[j] ] ;
                    }
            }
    }
    
    int main () {
            Euler () ;
            int n ;
            while (~ scanf ("%d" , &n)) printf ("%d
    " , phi[n]) ;
            return 0 ;
    }
    

      线性欧拉跟新:

    #include<cstdio>
    #include<iostream>
    using namespace std;
    int prime[100005],phi[1000005];
    int main(){
            int i,j;
            for(i=2;i<1000002;++i){
                    if(!phi[i]){
                            phi[i]=i-1;
                            prime[++prime[0]]=i;
                    }
                    for(j=1;j<=prime[0]&&(long long)i*prime[j]<1000002;++j)
                            if(i%prime[j])phi[i*prime[j]]=phi[i]*(prime[j]-1);
                            else{
                                    phi[i*prime[j]]=phi[i]*prime[j];
                                    break;
                            }
            }
            int T,n;
            scanf("%d",&T);
            while(T--){
                    scanf("%d",&n);
                    printf("%d
    ",phi[n+1]);
            }
    }
    

      

  • 相关阅读:
    POI处理Excel工具类
    Mac打开隐藏文件夹
    markdown语法
    U盘分区合并
    数组
    Java插入到mysql数据库显示问号?
    使用vmware打开别人提供好的vmx没反应怎么办?
    求长方形的外接圆
    读取mysql数据库
    excel对列的常用操作
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4747832.html
Copyright © 2011-2022 走看看