P13497 【MX-X14-T7】墓碑密码
有点不太像题了,感觉非常诡异,写之前真没觉得能过。
显然如果可以求出
问题在于如何快速求出
于是容易写出更加直接的答案:
计算上式也很简单,先对于每个
由于
但是这样子空间爆炸了,实际上也容易解决,枚举
最后回答询问有一些细节需要处理,如果每次暴力
时间复杂度
给个部分代码,正常写就能直接过,常数很小。
int n,m,q,a[205],b[205],g[205],dp[205];
ull f1[(1<<20)+5],f2[(1<<20)+5],f3[(1<<20)+5],f4[(1<<20)+5],sta1[25],sta2[25],sta3[25],sta4[25];
int sf[50000205];
inline void solveit(int v){
f1[0]=f2[0]=f3[0]=f4[0]=0;
for(int i=0;i<min(64,n);i++)
if(__builtin_popcountll(v&a[i])&1)f1[0]|=(1ull<<i);
for(int i=64;i<n;i++)
if(__builtin_popcountll(v&a[i])&1)f2[0]|=(1ull<<(i-64));
for(int i=0;i<min(64,m);i++)
if(__builtin_popcountll(v&b[i])&1)f3[0]|=(1ull<<i);
for(int i=64;i<m;i++)
if(__builtin_popcountll(v&b[i])&1)f4[0]|=(1ull<<(i-64));
for(int i=0;i<(1<<20);i++){
if(i){
int p=i^(i&-i),x=__builtin_ctz(i);
f1[i]=(f1[p]^sta1[x]);
f2[i]=(f2[p]^sta2[x]);
f3[i]=(f3[p]^sta3[x]);
f4[i]=(f4[p]^sta4[x]);
}
int c=__builtin_popcountll(f1[i])+__builtin_popcountll(f2[i]);
int c2=__builtin_popcountll(f3[i])+__builtin_popcountll(f4[i]);
int v=dec(m,2*c2);
g[c]=add(g[c],v);
}
}
inline void solve(){
gi(n),gi(m);
for(int i=0;i<n;i++)gi(a[i]);
for(int i=0;i<m;i++)gi(b[i]);
for(int i=0;i<20;i++){
for(int j=0;j<min(64,n);j++)if((1<<(i+8))&a[j])sta1[i]|=(1ull<<j);
for(int j=64;j<n;j++)if((1<<(i+8))&a[j])sta2[i]|=(1ull<<(j-64));
}
for(int i=0;i<20;i++){
for(int j=0;j<min(64,m);j++)if((1<<(i+8))&b[j])sta3[i]|=(1ull<<j);
for(int j=64;j<m;j++)if((1<<(i+8))&b[j])sta4[i]|=(1ull<<(j-64));
}
for(int w=0;w<(1<<8);w++)solveit(w);
int xs=qkpow((1<<28),mod-2);
for(int i=0;i<=n;i++){
for(int j=0;j<=i;j++){
for(int k=0;k<=n-i;k++){
int v=1ll*binom(i,j)*binom(n-i,k)%mod*g[i]%mod;
if(j&1)dp[j+k]=dec(dp[j+k],v);
else dp[j+k]=add(dp[j+k],v);
}
}
}
gi(q);
while(q--){
int N;
gi(N);
int res=0;
for(int i=0;i<=n;i++){
if(N>=i){
int lim=(N-i)/2;
int pro=1ll*fac[lim+n]*inv[lim]%mod;
res=add(res,1ll*pro*inv[n]%mod*dp[i]%mod);
}
}
pi(1ll*res*xs%mod);
}
}