zoukankan      html  css  js  c++  java
  • 模板

    线性筛质数,可以通过输出ptop之后调整p数组的大小。pm[i]表示i的最小质因子,pk[i]表示含有i的最小质因子的幂。其他的积性函数主要依靠pk的值来求解,比如现在枚举的是t,求出了他的最小质因子的幂pk[t],那么t/pk[t]与pk[t]显然是互质的。当t==pk[t]时,则t是p[j]的幂次,一般积性函数在质数的幂次都要特殊求解,不过欧拉函数和莫比乌斯函数可以直接从低一级的幂次转移过来。当t!=pk[t]时,直接分解成两个互质的数的乘积。要注意这个算法的空间消耗巨大。

    1ex内的质数数量:

    1e1|4
    1e2|25
    1e3|168
    1e4|1229
    1e5|9592
    1e6|78498
    1e7|664579
    1e8|5761455
    

    其他常见的上界:

    2e5|17984
    2e6|148933
    2e7|1270607
    5e5|41538
    5e6|348513
    5e7|3001134
    

    第一个严格大于上界的最小质数连乘:

    2*3*5 = 30 > 10 = 1e1
    2*3*5*7 = 210 > 100 = 1e2
    2*3*5*7*11 = 2310 > 1000 = 1e3
    2*3*5*7*11*13 = 30030 > 10000 = 1e4
    2*3*5*7*11*13*17 = 510510 > 100000 = 1e5
    2*3*5*7*11*13*17*19 = 9699690 > 1000000 = 1e6
    2*3*5*7*11*13*17*19*23 = 223092870 > 10000000 = 1e7
    

    注意这个是严格大于,假如保证在上界以内的话事实上是少一个的。所以1e9内每个数的质因数的种类都不超过10种。

    const int MAXN = 1e7;
    int p[MAXN + 5], ptop;
    int pm[MAXN + 5], pk[MAXN + 5];
    
    void sieve() {
        int n = MAXN;
        pm[1] = 1;
        pk[1] = 1;
        for(int i = 2; i <= n; ++i) {
            if(!pm[i]) {
                p[++ptop] = i;
                pm[i] = i;
                pk[i] = i;
            }
            for(int j = 1; j <= ptop; ++j) {
                int t = i * p[j];
                if(t > n)
                    break;
                pm[t] = p[j];
                if(i % p[j]) {
                    pk[t] = pk[p[j]];
                } else {
                    pk[t] = pk[i] * p[j];
                    break;
                }
            }
            //printf("i=%d pm=%d pk=%d
    ", i, pm[i], pk[i]);
        }
        //printf("ptop=%d
    ",ptop);
        /*for(int i=1;i<=ptop;++i)
            printf("%d:%d
    ",i,p[i]);*/
    }
    

    判断一个数是不是质数只需要判断pm[i]=i。判断一个数是不是质数的幂只需要判断pk[i]=i。当然1是奇异的,特殊处理就可以了。

    很多时候只是需要质数,那么这样写比较省空间,也比较快。

    const int MAXN = 1e7;
    int p[MAXN + 5], ptop;
    bool pn[MAXN + 5];
    
    void sieve() {
        int n = MAXN;
        pn[1] = 1;
        for(int i = 2; i <= n; ++i) {
            if(!pn[i])
                p[++ptop] = i;
            for(int j = 1; j <= ptop; ++j) {
                int t = i * p[j];
                if(t > n)
                    break;
                pn[t] = 1;
                if(i % p[j] == 0)
                    break;
            }
        }
        printf("ptop=%d
    ", ptop);
        /*for(int i = 1; i <= ptop; ++i)
            printf("%d:%d
    ", i, p[i]);*/
    }
    
  • 相关阅读:
    跨域导致FormsAuthentication.Decrypt报错:填充无效,无法被移除
    Php构造函数construct的前下划线是双的_
    DNN学习资源整理
    改进housemenu2使网站导航亲Seo并在新窗口中打开。
    推荐10款非常优秀的 HTML5 开发工具
    Ext.Net系列:安装与使用
    Devexpress 破解方法
    Microsoft Visual Studio 2010 遇到了异常,可能是由某个扩展导致的
    浮躁和互联网
    chrome 默认以 https打开网站
  • 原文地址:https://www.cnblogs.com/KisekiPurin2019/p/11969510.html
Copyright © 2011-2022 走看看