zoukankan      html  css  js  c++  java
  • 【CodeForces】915 G. Coprime Arrays 莫比乌斯反演

    【题目】G. Coprime Arrays

    【题意】当含n个数字的数组的总gcd=1时认为这个数组互质。给定n和k,求所有sum(i),i=1~k,其中sum(i)为n个数字的数组,每个数字均<=i,总gcd=1的方案数。n<=2*10^6。答案将所有sum(i)处理成一个数字后输出。

    【算法】数论(莫比乌斯反演)

    【题解】假设当前求sum(k),令f(i)表示gcd=i的数组方案数,F(i)表示i|gcd的数组的方案数。

    因为F(x)=Σx|df(d),由莫比乌斯反演定理,f(x)=Σx|dμ(d/x)*F(d)。

    又F(x)=(k/x)^n,所以f(1)=Σμ(d)*(k/d)^n,d=1~k

    初始k=1,当k++时ans+=Σd|kμ(d)*((k/d)^n-(k/d-1)^n),这个过程只需要k ln k枚举贡献答案即可,同时预处理快速幂。

    复杂度O(k log n+k ln k)。

    #include<cstdio>
    const int N=2000010,MOD=1e9+7;
    int n,m,miu[N],prime[N],mark[N],sum[N],p[N],tot,ans,ANS;
    int pow(int x,int k){
        if(!x)return 0;
        int ans=1;
        while(k){
            if(k&1)ans=1ll*ans*x%MOD;
            x=1ll*x*x%MOD;
            k>>=1;
        }
        return ans;
    }
    int main(){
        scanf("%d%d",&n,&m);
        miu[1]=1;
        for(int i=2;i<=m;i++){
            if(!mark[i]){miu[prime[++tot]=i]=-1;}
            for(int j=1;j<=tot&&i*prime[j]<=m;j++){
                mark[i*prime[j]]=1;
                if(i%prime[j]==0)break;
                miu[i*prime[j]]=-miu[i];
            }
        }
        for(int i=0;i<=2000000;i++)p[i]=pow(i,n);
        for(int i=1;i<=m;i++){
            for(int j=i;j<=m;j+=i)sum[j]=((sum[j]+1ll*miu[i]*(p[j/i]-p[j/i-1]))%MOD+MOD)%MOD;
            ans=(ans+sum[i])%MOD;
            ANS=(ANS+(ans^i))%MOD;
        }
        printf("%d",ANS);
        return 0;
    }
    View Code
  • 相关阅读:
    PHP ceil() 函数
    PHP Array 函数
    php中的include()的使用技巧
    [观察者模式]在游戏开发中的应用
    [策略模式]在游戏开发中的应用
    使用EA将源码转化为类图
    PAT 1013 数素数 (20)
    PAT 1034 有理数四则运算(20)
    PAT 1033 旧键盘打字(20)
    PAT 1032 挖掘机技术哪家强(20)
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8288709.html
Copyright © 2011-2022 走看看