zoukankan      html  css  js  c++  java
  • 线性筛 欧拉筛

    线性筛

    int prime[maxl];
    bool mark[maxl];
    int tot;
    inline void oula()
    {
        for(int i=2;i<=maxl;i++)
        {
            if(!mark[i])prime[++tot]=i;
            for(int j=1;j<=tot and i+prime[j]<=maxl;j++){
                mark[i*prime[j]]=1;
                if(i%prime[j]==0)break;
            }
        }
    }

    最后一行代码是为了保证不重复。

    可以顺便求欧拉函数的φ值。欧拉函数的值φx是x以内与x互素的数的个数。φ是积性函数,性质如下:

    若n是素数,φn=n-1。

    若n是质数p的k次幂:

    φn=pk-pk-1=(p-1)pk-1

    若m与n互质:

    φ(mn)=φm*φn

    若要求单个数的phi值:

    BZOJ2705

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define ll long long
    using namespace std;
    ll n,ans;
    int m;
    ll phi(ll x)
    {
        ll t=x;
        for(ll i=2;i<=m;i++)
            if(x%i==0)
            {
                t=t/i*(i-1);
                while(x%i==0)x/=i;
            }
        if(x>1)t=t/x*(x-1);
        return t;
    }
    int main()
    {
        scanf("%lld",&n);
        m=sqrt(n);
        for(int i=1;i<=m;i++)
            if(n%i==0)
            {
                ans+=(ll)i*phi(n/i);
                if(i*i<n)ans+=(ll)(n/i)*phi(i);  
            }
        printf("%lld",ans);
        return 0;
    }

    如要算出范围内所有的phi值:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int maxn=1e8;
    inline int read()
    {
        int x=0;char c=getchar();
        while(!isdigit(c))c=getchar();
        while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
        return x; 
    }
    int phi[maxn],prime[maxn>>1],tot,n,ans;
    bool mark[maxn];
    inline void oula()
    {
        phi[1]=1;
        for(int i=2;i<=n;i++)
        {
            if(!mark[i])
            {
                prime[++tot]=i;
                phi[i]=i-1;
            }
            for(int j=1;j<=tot and i*prime[j]<=n;j++)
            {
                mark[i*prime[j]]=1;
                if(i%prime[j]==0)phi[i*prime[j]]=phi[i]*prime[j];
                else phi[i*prime[j]]=phi[i]*(prime[j]-1);
           if(i%prime[j])break; } } }
    int main() { n=read();
       int m=read(); oula(); while(m--)printf("%d ",prime[read()]); return 0; }

     注意φ1=1.

  • 相关阅读:
    CodeForces 906D (欧拉降幂)
    洛谷4139 bzoj 3884 上帝与集合的正确用法
    The Preliminary Contest for ICPC Asia Nanjing 2019ICPC南京网络赛
    主席树之初见
    HDU 6709“Fishing Master”(贪心+优先级队列)
    [数论]拓展中国剩余定理
    [数论] 求逆元
    2019 年百度之星·程序设计大赛
    2019 年百度之星·程序设计大赛
    pb_ds中的hash_table
  • 原文地址:https://www.cnblogs.com/BrotherHood/p/13149409.html
Copyright © 2011-2022 走看看