CodeForces803F Coprime Subsequences

题意:给一个n个数的序列(n<1e5),问有几个子序列是gcd == 1的

题解:莫比乌斯或者容斥,直接考虑,f(1) = mu[1]*F(1)+mu[2]*F(2)+....F[n]是2^(因子为n的数的个数)-1

#include <bits/stdc++.h>
#define maxn 100100
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
bool isprime[maxn];
const ll mod = 1e9+7;
ll num=0, mu[maxn], prime[maxn], a[maxn], dir[maxn];
void mobi(ll n){
    memset(isprime, true, sizeof(isprime));
    isprime[1] = false;
    mu[1] = 1;
    for(ll i=2;i<n;i++){
        if(isprime[i]){
            prime[num++] = i;
            mu[i] = -1;
        }
        for(ll j=0;j<num;j++){
            if(i*prime[j] > n) break;
            isprime[i*prime[j]] = false;
            if(i%prime[j]==0){
                mu[i*prime[j]] = 0;
                break;
            }
            else mu[i*prime[j]] = -mu[i];
        }
    }
}
ll power(ll x,ll t){
    ll ans=1;
    x %= mod;
    while(t){
        if(t&1) ans = ans*x%mod;
        x = x*x%mod;
        t >>= 1;
    }
    return (ans-1)%mod;
}
int main(){
    ll n, ans = 0;
    scanf("%lld", &n);
    mobi(100001);
    for(ll i=0;i<n;i++){
        scanf("%lld", &a[i]);
        for(ll j=1;j*j<=a[i];j++){
            if(a[i] % j == 0){
                dir[j]++;
                if(j != a[i]/j) dir[a[i]/j]++;
            }
        }
    }
    for(ll i=1;i<=100000;i++){
        ans = (ans+mu[i]*power(2, dir[i]))%mod;
    }
    printf("%lld\n", (ans+mod)%mod);
    return 0;
}
View Code

 

posted on 2017-10-09 21:48  2855669158  阅读(147)  评论(0编辑  收藏  举报

导航