zoukankan      html  css  js  c++  java
  • [容斥原理][莫比乌斯反演] 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;
    }
    
  • 相关阅读:
    Scrapy 概览笔记
    Python 依赖版本控制 (requirements.txt 文件生成和使用)
    Python 虚拟空间的使用
    macOS 所有版本 JDK 安装指南 (with Homebrew)
    鉴权那些事
    Java 位运算符和 int 类型的实现
    ASP.NET Core 入门教程 5、ASP.NET Core MVC 视图传值入门
    如何做好一次知识或技术分享
    ASP.NET Core 入门教程 4、ASP.NET Core MVC控制器入门
    ASP.NET Core 入门教程 3、ASP.NET Core MVC路由入门
  • 原文地址:https://www.cnblogs.com/AEMShana/p/12591554.html
Copyright © 2011-2022 走看看