CF585E Present for Vitalik the Philatelist

时间:2019-12-03
本文章向大家介绍 CF585E Present for Vitalik the Philatelist,主要包括 CF585E Present for Vitalik the Philatelist使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

分析

计数题,考虑容斥。

然后这种和 gcd 有关的题,可以考虑枚举 gcd。

先考虑对于枚举的这个数是质数的情况,设枚举到 x,x 的倍数有 num 个,那么贡献有 \((2^{num}-1)*(n-num)\)

那么考虑 x 是合数的情况,x 的可能情况在枚举 x 的所有约数时都会计算,所以很自然可以考虑到用莫比乌斯函数当容斥系数,然后得是负的莫比乌斯函数。

code:

#include<bits/stdc++.h>
using namespace std;
const int M=5e5+7;
const int N=1e7+7;
const int mod=1e9+7;
template <class I>
inline void read(I &x){
    int f=1;
    char c;
    for(c=getchar();c<'0'||c>'9';c=getchar()) if(c=='-') f=-1;
    for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+(c&15),c=getchar());
    x*=f;
}
int n,mu[N],tot,primes[N],cnt[N],jc[M],mx;
bool v[N];
void sieve(){
    for(int i=2;i<=mx;i++){
        if(!v[i]) primes[++tot]=i,mu[i]=-1;
        for(int j=1;j<=tot;j++){
            if(1ll*i*primes[j]>mx) break;
            v[i*primes[j]]=1;
            if(!(i%primes[j])) break;
            mu[i*primes[j]]=-mu[i];
        }
    }
}
int ans;
int main(){
    read(n);
    jc[0]=1;
    int a;
    for(int i=1;i<=n;i++)
        read(a),cnt[a]++,mx=max(mx,a),jc[i]=jc[i-1]*2%mod;
    sieve();
    for(int i=2;i<=mx;i++){
        if(!mu[i]) continue;
        int num=0;
        for(int j=i;j<=mx;j+=i)
            num+=cnt[j];
        ans=((ans-1ll*mu[i]*(n-num)*(jc[num]-1))%mod+mod)%mod;
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Hikigaya/p/11977937.html