Codeforces 1043F(容斥+dp)

Posted duskob

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
",i);return 0;}
        }
    }
}

  

 

以上是关于Codeforces 1043F(容斥+dp)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #759 F(容斥+线段树维护dp)

CodeForces - 285E: Positions in Permutations(DP+组合数+容斥)

Jzzhu and Numbers CodeForces - 449D (容斥,dp)

Codeforces 1245F. Daniel and Spring Cleaning(容斥原理+数位DP)

Codeforces Round #257 (Div. 1) D - Jzzhu and Numbers 容斥原理 + SOS dp

Codeforces Round #589 (Div. 2)E(组合数,容斥原理,更高复杂度做法为DP)