ARC093 F Dark Horse——容斥
题目:https://atcoder.jp/contests/arc093/tasks/arc093_d
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=20,M=(1<<16)+5,mod=1e9+7; int pw(int x,int k) {int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;} int n,m,a[N],jc[M],jcn[M],bin[N],f[N][M],ct[M]; bool cmp(int a,int b){return a>b?a:b;} int C(int n,int m) { if(n<0||m<0||n<m)return 0; return (ll)jc[n]*jcn[m]%mod*jcn[n-m]%mod; } void init() { bin[0]=1;for(int i=1;i<=16;i++)bin[i]=bin[i-1]<<1; int lm=bin[n]; jc[0]=1;for(int i=1;i<=lm;i++)jc[i]=(ll)jc[i-1]*i%mod; jcn[lm]=pw(jc[lm],mod-2); for(int i=lm-1;i>=0;i--)jcn[i]=(ll)jcn[i+1]*(i+1)%mod; for(int s=1;s<bin[n];s++) ct[s]=ct[s^(s&-s)]+1; for(int s=0;s<bin[n];s++)ct[s]=(ct[s]&1)?mod-1:1; } int main() { scanf("%d%d",&n,&m); init(); for(int i=1;i<=m;i++)scanf("%d",&a[i]); sort(a+1,a+m+1,cmp); f[0][0]=1; int lm=bin[n]; for(int i=1;i<=m;i++) for(int s=0;s<bin[n];s++) { f[i][s]=f[i-1][s]; for(int j=0;j<n;j++) if(s&bin[j]) { int t=s^bin[j]; int ml=(ll)f[i-1][t]*C(lm-a[i]-t,bin[j]-1)%mod; f[i][s]=(f[i][s]+(ll)ml*jc[bin[j]])%mod; } } int ans=0; for(int s=0,U=bin[n]-1;s<bin[n];s++) { ans=(ans+(ll)ct[s]*f[m][s]%mod*jc[U^s])%mod; } printf("%lld\n",(ll)ans*lm%mod); return 0; }