bzoj 2839 集合计数——二项式反演
Posted narh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2839 集合计数——二项式反演相关的知识,希望对你有一定的参考价值。
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2839
设 ( g(i) ) 表示至少有 i 个, ( f(i) ) 表示恰好有 i 个,则
( g(i)=C_{n}^{i}*(2^{2^{n-i}}-1) )
( g(i)=sumlimits_{j=i}^{n}C_{j}^{i}f(j) )
( f(i)=sumlimits_{j=i}^{n}(-1)^{j-i}C_{j}^{i}g(j) )
以为把 g 写出来后 ( C_{n}^{i}*C_{i}^{j} = C_{n}^{j} ) ,然而其实 ( C_{n}^{i}*C_{i}^{j} = C_{n}^{j}*C_{n-j}^{i-j} ) 。
注意指数取模是 mod-1 。
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=1e6+5,mod=1e9+7; int n,k,g[N],jc[N],jcn[N]; void upd(int &x){x>=mod?x-=mod:0;x<0?x+=mod:0;} int pw(int x,int k,int md=mod) {int ret=1;while(k){if(k&1)ret=(ll)ret*x%md;x=(ll)x*x%md;k>>=1;}return ret;} void init() { jc[0]=1;for(int i=1;i<=n;i++)jc[i]=(ll)jc[i-1]*i%mod; jcn[n]=pw(jc[n],mod-2);for(int i=n-1;i>=0;i--)jcn[i]=(ll)jcn[i+1]*(i+1)%mod; } int C(int n,int m) {return (ll)jc[n]*jcn[m]%mod*jcn[n-m]%mod;} int main() { scanf("%d%d",&n,&k); init(); int ans=0; for(int i=k,j=1;i<=n;i++,j=-j) ans=(ans+(ll)j*C(i,k)*C(n,i)%mod*(pw(2,pw(2,n-i,mod-1))-1))%mod,upd(ans); printf("%d ",ans); return 0; }
以上是关于bzoj 2839 集合计数——二项式反演的主要内容,如果未能解决你的问题,请参考以下文章