Codeforces 1043F(容斥+dp)

题目链接

题意:是否存在选择方案使所选的数gcd=1

思路:f[i][j]表示选i个数gcd=j的方案数,cnt[i]表示包含因子i的数的个数,

        则f[i][j]=C(cnt[j],i)-f[i][d],j|d,j<d

#include <bits/stdc++.h>
#define DBG(x) cerr << #x << " = " << x << endl;
const int maxn = 3e5+5;
const int mod  = 1e9+7;
using namespace std;
typedef long long LL;

int n,a[maxn];
int tmp,cnt[maxn];
LL f[15][maxn];
LL inv[maxn],fac[maxn];

LL qpow(LL a,LL b,LL p){
    LL res=1;
    while(b){
        if(b&1)res=(res*a)%p;
        a=(a*a)%p;
        b>>=1;
    }
    return res%p;
}

int C(int a,int b){
    return ((((fac[a]*inv[b])%mod)*inv[a-b])%mod)%mod;
}

void init(){
    for(int i=1;i<maxn;i++)
        for(int j=i+i;j<maxn;j+=i)cnt[i]+=cnt[j];
    fac[0]=1;for(int i=1;i<=n;i++)fac[i]=(fac[i-1]*i)%mod;
    inv[n]=qpow(fac[n],mod-2,mod);
    for(int i=n;i>=1;i--)inv[i-1]=(inv[i]*1LL*i)%mod;
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        cnt[a[i]]++;
        f[1][a[i]]++;
        tmp=((i == 1) ? a[i] : __gcd(tmp,a[i]));
    }
    if(tmp != 1){puts("-1");return 0;}
    else{
        init();
        for(int i=1;i<=7;i++){
            for(int j=maxn-1;j>=1;j--){
                f[i][j]=C(cnt[j],i);
                for(int k=j+j;k<maxn;k+=j)f[i][j]=(f[i][j]-f[i][k]+mod)%mod;
            }
            if(f[i][1] > 0){printf("%d\n",i);return 0;}
        }
    }
}

  

 

猜你喜欢

转载自www.cnblogs.com/DuskOB/p/10006757.html