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