题解:P8189 [USACO22FEB] Redistributing Gifts G
怎么都不写哈集幂喵!怎么还有
考虑先将题意转化,观察到要求交换后的优先嘟比交换前的优先嘟高,可以直接将当前的
#include<bits/stdc++.h>
#define int int64_t
using namespace std;
int n,q,a[18][18],e[18][18],f[262144],h[262144],tmp[262144],S,g[262144][18];
string str;
namespace fwt{
int f[1048576],g[1048576],h[1048576];
void fwtor(int n,int*f,int mul){
for(int i=1;i<1<<n;i<<=1)
for(int j=0,p=i<<1;j<1<<n;j+=p)
for(int k=0;k<i;k++)
f[i+j+k]+=f[j+k]*mul;
}
void _or(int n,int*a,int*b,int*c){
memcpy(f,a,(1<<n)*sizeof(a)),memcpy(g,b,(1<<n)*sizeof(b)),fwtor(n,f,1),fwtor(n,g,1);
for(int i=0;i<1<<n;i++)
h[i]=f[i]*g[i];
fwtor(n,h,-1),memcpy(c,h,sizeof(h));
}
}
namespace Subset{
using namespace fwt;
int f[19][262144],g[19][262144],h[19][262144];
void subset(int n,int*a,int*b){
memset(f,0,sizeof(f)),memset(g,0,sizeof(g)),memset(h,0,sizeof(h));
for(int s=0,x;s<1<<n;s++)
x=__builtin_popcount(s),f[x][s]=a[s],g[x][s]=b[s];
for(int i=0;i<=n;i++){
fwtor(n,f[i],1),fwtor(n,g[i],1);
for(int j=0,k=i;j<=i;j++,k--)
for(int s=0;s<1<<n;s++)
h[i][s]+=f[j][s]*g[k][s];
fwtor(n,h[i],-1);
}
for(int s=0;s<1<<n;s++)
if(s>>(n-1)&1)
a[s]=h[__builtin_popcount(s)][s];
}
}
int32_t main(){
ios::sync_with_stdio(0),cin.tie(0),cin>>n,f[0]=1;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
cin>>a[i][j],a[i][j]--;
for(int j=0;j<n;j++){
if(a[i][j]==i)
break;
e[i][a[i][j]]=1;
}
h[1<<i]=g[1<<i][i]=1;
}
for(int s=1,p;s<1<<n;s++){
p=__builtin_ctz(s);
for(int i=p;i<n;i++)
if(s>>i&1&&g[s][i]){
if(e[i][p])
h[s]+=g[s][i];
for(int j=p+1;j<n;j++)
if(!(s>>j&1)&&e[i][j])
g[s|1<<j][j]+=g[s][i];
}
}
for(int m=1;m<=n;m++)
Subset::subset(m,f,h);
cin>>q;
while(q--){
cin>>str,S=0;
for(int i=0;i<n;i++)
S|=(str[i]=='H')<<i;
cout<<f[S]*f[S^((1<<n)-1)]<<'\n';
}
return 0;
}