ABC321G
其实赛时可能可以做出来的,只是打了前 6 道想下班了,有点小小遗憾。
首先问题看起来很唬人,考虑转换一下。考虑已经固定
这个答案显然不是
然后怎么办呢?
作者表示再做一遍 dp,
但是事实上
code:
点击查看代码
int n,m,e[23],d[23],f[N],g[N],h[N],c[N];
il int Mod(int x,int y){return x+y>=mod?x+y-mod:x+y;}
il int lowbit(int x){return x&(-x);}
il int qpow(int x,int y){
int ret=1;
while(y){
if(y&1)ret=1ll*ret*x%mod;
x=1ll*x*x%mod;y>>=1;
}
return ret;
}
void Yorushika(){
scanf("%d%d",&n,&m);
f[0]=1;
rep(i,1,m){
int x;scanf("%d",&x);
e[x]++;
f[i]=1ll*f[i-1]*i%mod;
}
rep(i,1,m){
int x;scanf("%d",&x);
d[x]++;
}
const int k=1<<n;
int ans=0;
rep(i,1,k-1){
rep(j,0,n-1){
g[i]+=e[j+1]*(i>>j&1);
h[i]+=d[j+1]*(i>>j&1);
}
if(g[i]!=h[i])
continue;
c[i]=f[g[i]];
for(int j=(i-1)&i;j;j=(j-1)&i){
if(g[j]!=h[j]||lowbit(i)!=lowbit(j))
continue;
c[i]=Mod(c[i],mod-1ll*c[j]*f[g[i]-g[j]]%mod);
}
ans=Mod(ans,1ll*c[i]*f[m-g[i]]%mod);
}
printf("%lld\n",1ll*ans*qpow(f[m],mod-2)%mod);
}
signed main(){
int t=1;
// scanf("%d",&t);
while(t--)
Yorushika();
}