#include<iostream>#define int long longusingnamespacestd;constintN=50;intn,ans;inta[N];intc(inta,intb){intres=1;for(inti=a;i>=a-b+1;i--)res*=i;for(inti=b;i>=1;i--)res/=i;returnres;}intfact(intx){intres=1;for(inti=1;i<=x;i++)res=res*i;returnres;}signedmain(){cin>>n;for(inti=0;i<=n;i++)a[i]=c(n,i)*fact(n-i);for(inti=0;i<=n;i+=2)ans+=a[i];for(inti=1;i<=n;i+=2)ans-=a[i];cout<<ans<<'\n';return0;}
#include<iostream>#define int long longusingnamespacestd;constintN=1e6+10;constintMOD=1e9+7;intn,k,ans;intinv[N],fact[N],ifact[N];intpw2[N];#define add(a, b) a = (a + b) % MOD;#define sub(a, b) a = (a + MOD - b) % MOD;inlineintc(inta,intb){returnfact[a]*ifact[a-b]%MOD*ifact[b]%MOD;}inlineintqpow(inta,intb){intres=1;while(b){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}returnres;}inta[N];signedmain(){cin>>n>>k;inv[1]=1;fact[0]=ifact[0]=1;pw2[0]=1;for(inti=2;i<=n;i++)inv[i]=MOD-inv[MOD%i]*(MOD/i)%MOD;for(inti=1;i<=n;i++)fact[i]=fact[i-1]*i%MOD;for(inti=1;i<=n;i++)ifact[i]=ifact[i-1]*inv[i]%MOD;for(inti=1;i<=n;i++)pw2[i]=pw2[i-1]*2%(MOD-1);for(inti=k;i<=n;i++)a[i]=c(n,i)*(qpow(2,pw2[n-i])+MOD-1)%MOD;for(inti=k;i<=n;i+=2)add(ans,c(i,k)*a[i]%MOD);for(inti=k+1;i<=n;i+=2)sub(ans,c(i,k)*a[i]%MOD);cout<<ans<<'\n';return0;}
#include<iostream>#define int long longusingnamespacestd;constintN=2010;constintMOD=1e9+7;intn,m,ans;inta[N];intinv[N],fact[N],ifact[N];ints[N];intc(intx,inty){returnfact[x]*ifact[x-y]%MOD*ifact[y]%MOD;}signedmain(){inv[1]=fact[0]=ifact[0]=1;for(inti=2;i<N;i++)inv[i]=MOD-inv[MOD%i]*(MOD/i)%MOD;for(inti=1;i<N;i++)fact[i]=fact[i-1]*i%MOD;for(inti=1;i<N;i++)ifact[i]=ifact[i-1]*inv[i]%MOD;cin>>n>>m;for(inti=1;i<=m;i++)cin>>a[i];for(intk=0;k<n;k++){s[k]=c(n,k);for(inti=1;i<=m;i++)s[k]=s[k]*c(a[i]+n-k-1,n-k-1)%MOD;}for(inti=0;i<=n;i+=2)ans=(ans+s[i])%MOD;for(inti=1;i<=n;i+=2)ans=(ans+MOD-s[i])%MOD;cout<<ans<<'\n';return0;}
#include<iostream>#include<algorithm>#define int long longusingnamespacestd;constintN=2010;constintMOD=1e9+9;#define add(a, b) a = (a + b) % MODintfact[N],ifact[N],inv[N];intc(inta,intb){returnfact[a]*ifact[a-b]%MOD*ifact[b]%MOD;}intn,k,ans;inta[N],b[N];intf[N];signedmain(){inv[1]=fact[0]=ifact[0]=1;for(inti=2;i<N;i++)inv[i]=MOD-inv[MOD%i]*(MOD/i)%MOD;for(inti=1;i<N;i++)fact[i]=fact[i-1]*i%MOD;for(inti=1;i<N;i++)ifact[i]=ifact[i-1]*inv[i]%MOD;cin>>n>>k;for(inti=1;i<=n;i++)cin>>a[i];for(inti=1;i<=n;i++)cin>>b[i];if((n&1)!=(k&1)){cout<<"0\n";return0;}k=(n+k)>>1;sort(a+1,a+1+n);sort(b+1,b+1+n);for(inti=1;i<=n;i++){intp=lower_bound(b+1,b+1+n,a[i])-b-1;f[0]=1;for(intj=min(i,p);j>=1;j--){add(f[j],f[j-1]*(p-j+1)%MOD);}}for(inti=0;i<=n;i++)f[i]=f[i]*fact[n-i]%MOD;for(inti=k;i<=n;i+=2)add(ans,c(i,k)*f[i]%MOD);for(inti=k+1;i<=n;i+=2)add(ans,MOD-c(i,k)*f[i]%MOD);cout<<ans<<'\n';return0;}
#include<iostream>#define int long longusingnamespacestd;constintN=1e5+10;intc0,c1,c2,c3;intd0,d1,d2,d3;intq,s,ans;intf[N];intcalc(intx){inttmp=s;if(x&1)tmp-=c0*d0;if(x&2)tmp-=c1*d1;if(x&4)tmp-=c2*d2;if(x&8)tmp-=c3*d3;if(tmp<0)return0;return(__builtin_popcount(x)&1)?-f[tmp]:f[tmp];}signedmain(){cin>>c0>>c1>>c2>>c3;f[0]=1;for(inti=0;i<=100000-c0;i++)f[i+c0]+=f[i];for(inti=0;i<=100000-c1;i++)f[i+c1]+=f[i];for(inti=0;i<=100000-c2;i++)f[i+c2]+=f[i];for(inti=0;i<=100000-c3;i++)f[i+c3]+=f[i];cin>>q;while(q--){cin>>d0>>d1>>d2>>d3>>s;++d0;++d1;++d2;++d3;ans=0;for(inti=0;i<16;i++)ans+=calc(i);cout<<ans<<'\n';}return0;}
#include<iostream>#define int long longusingnamespacestd;constintN=17;structEdge{intv,next;}pool[2*N+10];intne,head[N+5];voidaddEdge(intu,intv){pool[++ne]={v,head[u]};head[u]=ne;}intn,m,ans;intadj[N+5][N+5];intf[N+5][N+5],vld[N+5];voiddfs(intu,intfa){for(inti=0;i<=n;i++)f[u][i]=vld[i];for(inte=head[u];e;e=pool[e].next){intv=pool[e].v;if(v==fa)continue;dfs(v,u);for(inti=1;i<=n;i++){inttmp=0;for(intj=1;j<=n;j++){if(adj[i][j])tmp+=f[v][j];}f[u][i]=f[u][i]*tmp;}}}signedmain(){cin>>n>>m;for(inti=1;i<=m;i++){intu,v;cin>>u>>v;adj[u][v]=adj[v][u]=1;}for(inti=1;i<=n-1;i++){intu,v;cin>>u>>v;addEdge(u,v);addEdge(v,u);}for(inti=1;i<(1<<n);i++){for(intj=1;j<=n;j++)vld[j]=(i>>(j-1))&1;dfs(1,0);intres=0;for(inti=1;i<=n;i++)res+=f[1][i];if(__builtin_popcountll(((1<<n)-1)^i)&1)ans-=res;elseans+=res;}cout<<ans<<'\n';return0;}
#include<iostream>#define int long longusingnamespacestd;constintN=1010;constintMOD=998244353;inlineintqpow(inta,intb){intres=1;while(b){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}returnres;}structEdge{intv,next;}pool[2*N];intne,head[N];voidaddEdge(intu,intv){pool[++ne]={v,head[u]};head[u]=ne;}intn;intp[N][4];intsz[N],f[N][3*N];intinv[3*N];voiddfs(intu,intfa){f[u][0]=1;sz[u]=1;for(inte=head[u];e;e=pool[e].next){intv=pool[e].v;if(v==fa)continue;dfs(v,u);if(e&1){for(inti=3*(sz[u]+sz[v]);i>=0;i--){intsum=0;for(intj=max(0ll,i-3*sz[u]);j<=3*sz[v]&&j<=i;j++){sum=(sum+f[u][i-j]*f[v][j]%MOD)%MOD;}f[u][i]=sum;}}else{inttmp=0;for(intj=0;j<=3*sz[v];j++)tmp=(tmp+f[v][j])%MOD;for(inti=3*(sz[u]+sz[v]);i>=0;i--){intsum=tmp*f[u][i]%MOD;for(intj=max(0ll,i-3*sz[u]);j<=3*sz[v]&&j<=i;j++){sum=(sum+MOD-f[u][i-j]*f[v][j]%MOD)%MOD;}f[u][i]=sum;}}sz[u]+=sz[v];}for(inti=3*sz[u];i>=0;i--){intsum=0;for(intj=1;j<=3&&j<=i;j++){sum=(sum+f[u][i-j]*p[u][j]%MOD*j%MOD*inv[i]%MOD)%MOD;}f[u][i]=sum;}}signedmain(){ios::sync_with_stdio(0);cin.tie(0);inv[1]=1;for(inti=2;i<3*N;i++)inv[i]=MOD-inv[MOD%i]*(MOD/i)%MOD;cin>>n;for(inti=1;i<=n;i++){inta1,a2,a3,tmp;cin>>a1>>a2>>a3;tmp=qpow(a1+a2+a3,MOD-2);p[i][1]=a1*tmp%MOD;p[i][2]=a2*tmp%MOD;p[i][3]=a3*tmp%MOD;}for(inti=1;i<=n-1;i++){intu,v;cin>>u>>v;addEdge(u,v);addEdge(v,u);}dfs(1,0);intans=0;for(inti=1;i<=3*n;i++)ans=(ans+f[1][i])%MOD;cout<<ans<<'\n';return0;}
#include<iostream>#define int long longusingnamespacestd;constintN=17;constintMOD=998244353;structEdge{intu,v;}edg[N*N];intn,m;intadj[N+5][N+5];intpw2[N*N];intf[1<<N],g[1<<N];intans[N];signedmain(){pw2[0]=1;for(inti=1;i<N*N;i++)pw2[i]=pw2[i-1]*2%MOD;cin>>n>>m;for(inti=1;i<=m;i++)cin>>edg[i].u>>edg[i].v;for(inti=1;i<=m;i++)--edg[i].u,--edg[i].v;for(inti=0;i<(1<<n);i++){intcnt=0;for(intj=1;j<=m;j++){intu=edg[j].u,v=edg[j].v;if((i&(1<<u))&&(i&(1<<v)))++cnt;}g[i]=pw2[cnt];}f[1]=1;for(inti=3;i<(1<<n);i+=2){f[i]=g[i];intj=(i-1)&i;while(j){(f[i]+=MOD-f[j]*g[i^j]%MOD)%=MOD;j=(j-1)&i;}}for(inti=3;i<(1<<n);i+=2){intres=f[i]*g[((1<<n)-1)^i]%MOD;for(intj=0;j<n;j++){if(i&(1<<j))(ans[j+1]+=res)%=MOD;}}for(inti=2;i<=n;i++)cout<<ans[i]<<'\n';return0;}
#include<iostream>#include<iomanip>#define int long longusingnamespacestd;constintN=12;intn,ans;intpx[N],py[N],pr[N];intcnt[1<<N],w[N];intcalc(ints){intx=0,y=0,r=3e6+10;for(inti=0;i<n;i++){if(s>>i&1){intnx=max(x,px[i]),ny=max(y,py[i]);intnr=min(x+y+r-nx-ny,px[i]+py[i]+pr[i]-nx-ny);x=nx,y=ny,r=nr;if(r<0)return0;}}returnr*r;}signedmain(){cin>>n;for(inti=0;i<n;i++)cin>>px[i]>>py[i]>>pr[i];w[1]=1;for(inti=2;i<=n;i++)w[i]=w[i-1]*(-2);for(inti=1;i<(1<<n);i++){cnt[i]=cnt[i>>1]+(i&1);ans+=w[cnt[i]]*calc(i);}cout<<fixed<<setprecision(1)<<(double)ans/2<<'\n';return0;}
#include<iostream>#define int long longusingnamespacestd;constintN=1e5+10;constintMOD=1e9+7;structEdge{intv,next;}pool[2*N];intne=1,head[N];voidaddEdge(intu,intv){pool[++ne]={v,head[u]};head[u]=ne;}intinv[N],fact[N];intT;intn,k,ans;intdeg[N],dep[N],key[N];intf[N];voiddfs1(intu,intfa){dep[u]=dep[fa]+1;for(inte=head[u];e;e=pool[e].next){intv=pool[e].v;if(v==fa)continue;dfs1(v,u);}}voiddfs2(intu,intfa){f[u]=0;for(inte=head[u];e;e=pool[e].next){intv=pool[e].v;if(v==fa)continue;dfs2(v,u);if(!key[v]){ans=(ans+f[u]*f[v]%MOD)%MOD;f[u]=(f[u]+f[v]*inv[deg[u]-1]%MOD)%MOD;}else{ans=(ans+MOD-f[v])%MOD;ans=(ans+MOD-1)%MOD;ans=(ans+MOD-f[u])%MOD;f[u]=(f[u]+MOD-inv[deg[u]-1])%MOD;}}}voidclear(){for(inti=0;i<=n+5;i++)head[i]=key[i]=deg[i]=0;ne=1;ans=0;}signedmain(){inv[1]=fact[0]=1;for(inti=2;i<N;i++)inv[i]=MOD-inv[MOD%i]*(MOD/i)%MOD;for(inti=1;i<N;i++)fact[i]=fact[i-1]*i%MOD;cin>>T>>T;while(T--){cin>>n>>k;clear();for(inti=1;i<=n-1;i++){intu,v;cin>>u>>v;++deg[u],++deg[v];addEdge(u,v);addEdge(v,u);}dfs1(1,0);for(inti=1;i<=k;i++){inte,u,v;cin>>e;u=pool[2*e].v,v=pool[2*e+1].v;if(dep[v]<dep[u])swap(u,v);key[v]=1;}dfs2(1,0);ans=MOD-ans;for(inti=1;i<=n;i++)ans=ans*fact[deg[i]-1]%MOD;cout<<ans<<'\n';}return0;}
DAG 子图计数
给定一个有向图,请问有多少个边集是无环的。
\(n\le 17\)
考虑状压,设 \(f_S\) 表示点集 \(S\) 的答案。对于 DAG,我们可以枚举它的顶层节点(入度为 \(0\))组成的集合 \(T\),然后从 \(f_{S-T}\) 转移。然而这样做会将一个 DAG 算重多次:考虑拆贡献,对于一个 DAG,设它的顶层节点集合为 \(T_0\);那么只要我们枚举的 \(T\) 是真实的 \(T_0\) 的子集,就会将这个 DAG 计算一遍。
#include<iostream>#define int long longusingnamespacestd;constintN=15;constintMOD=1e9+7;intn,m;intadj[1<<N];intpw[300],cnt[1<<N];intf[1<<N],ans[1<<N];intess[1<<N],est[1<<N];signedmain(){pw[0]=1;for(inti=1;i<300;i++)pw[i]=pw[i-1]*2%MOD;for(inti=1;i<(1<<N);i++)cnt[i]=cnt[i>>1]+(i&1);cin>>n>>m;for(inti=1;i<=m;i++){intu,v;cin>>u>>v;--u,--v;adj[1<<u]|=1<<v;}for(ints=1;s<(1<<n);s++){for(inti=0;i<n;i++){if(!(s>>i&1))continue;for(intj=0;j<n;j++){if((s>>j&1)&&(adj[1<<i]>>j&1))++ess[s];}}}f[0]=ans[0]=1;for(ints=1;s<(1<<n);s++){intx=s&-s,is=(~s)&((1<<n)-1);for(intt=(s-1)&s;t>0;t=(t-1)&s){if(~t&x)continue;f[s]=(f[s]+MOD-ans[t]*f[s-t]%MOD)%MOD;}ans[s]=(ans[s]+f[s])%MOD;ans[s]=(pw[ess[s]]+ans[s])%MOD;f[s]=(f[s]+MOD-ans[s])%MOD;for(inttt=(is-1)&is;tt>0;tt=(tt-1)&is){intt=is^tt;est[t]=est[t-(t&-t)]+cnt[adj[t&-t]&s];}est[is]=est[is-(is&-is)]+cnt[adj[is&-is]&s];for(intt=is;t>0;t=(t-1)&is){ans[s+t]=(ans[s+t]+f[s]*pw[est[t]]%MOD*pw[ess[t]]%MOD);}}cout<<ans[(1<<n)-1]<<'\n';return0;}