• [容斥原理][莫比乌斯反演] Codeforces 803F Coprime Subsequences


    题目大意

    给你一个长为(n(nleq 10^5))的序列({a_n}),其中(a_ileq 10^5),求有多少个子序列的(gcd=1)。答案对(10^9+7)取模。

    题解

    (f(x)) 表示 (gcd=x) 的子序列的个数,则题目要求 (f(1))
    (g(x)) 表示满足 (gcd=kx,kin Z^+) 的子序列的个数。
    设在序列中,(x) 的倍数有 (cnt(x)) 个,则 (g(x)=2^{cnt(x)}-1)
    可以发现, (g(n)=sum_{n|d}f(d))
    由莫比乌斯反演定理可得 (f(n)=sum_{n|d}mu(frac{d}{n})g(d))
    (Ans=sum mu(d)(2^{cnt(d)}-1))
    线性筛出莫比乌斯函数,(O(Nsqrt{N})) 处理 (Cnt(x)) ,再枚举 (d)计算即可。

    Code

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    
    #define RG register int
    #define LL long long
    
    template<typename elemType>
    inline void Read(elemType &T){
        elemType X=0,w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        T=(w?-X:X);
    }
    
    const LL MOD=1000000007LL;
    int Mu[100010],Cnt[100010];
    vector<int> Prime;
    bool not_Prime[100010];
    int N;
    
    LL ex_Pow(LL b,LL n){
        LL x=1;
        LL Power=b%MOD;
        while(n){
            if(n&1) x=x*Power%MOD;
            Power=Power*Power%MOD;
            n>>=1;
        }
        return x;
    }
    
    inline void Get_Mu(int Len){
        Mu[1]=1;
        not_Prime[1]=1;
        int Size=0;
        for(RG i=2;i<=Len;i++){
            if(!not_Prime[i]){
                Prime.push_back(i);
                Mu[i]=-1;++Size;
            }
            for(RG j=0;j<Size;j++){
                int mid=Prime[j]*i;
                if(mid>Len) break;
                not_Prime[mid]=1;
                if(i%Prime[j]==0){Mu[i*Prime[j]]=0;break;}
                Mu[mid]=-Mu[i];
            }
        }
        return;
    }
    
    inline void Divide(int x){
        for(RG i=1;i<=sqrt(x);++i){
            if(x%i==0) {
                if(i==x/i) ++Cnt[i];
                else{++Cnt[i];++Cnt[x/i];}
            }
        }
        return;
    }
    
    
    int main(){
        Get_Mu(100000);
        Read(N);
        for(RG i=1;i<=N;++i){
            int x;Read(x);
            Divide(x);
        }
        LL Ans=0;
        for(RG i=1;i<=100000;++i)
            Ans=(Ans+(LL)Mu[i]*(ex_Pow(2,Cnt[i])-1LL))%MOD;
        Ans=(Ans+MOD)%MOD;
        printf("%I64d
    ",Ans);
        return 0;
    }
    
  • 相关阅读:
    python的类的继承和多继承
    python的类访问控制、私有属性
    python的面向对象、类方法和静态方法
    python的序列化和反序列化
    python高阶函数、柯里化、装饰器、参数注解
    python函数参数、参数解构、作用域、递归及匿名函数
    python内置函数列表解析、生成器
    python内置函数字典(dict)
    python内置函数集合(set)
    定制自己的打印函数---进阶篇
  • 原文地址:https://www.cnblogs.com/AEMShana/p/12591554.html
Copyright © 2020-2023  润新知