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
",(ll)ans*lm%mod);
  return 0;
}
原文地址:https://www.cnblogs.com/Narh/p/11001959.html