Cyclic Hamming (Hard Version)
Cyclic Hamming (Hard Version)
考虑 \(\sum h(s,t') = cnt_{0,s} \times cnt_{1,t} + cnt_{1,s} \times cnt_{0,t} = 2^{2k+1}\),则 \(h(s,t)\) 的平均数为 \(\dfrac{2^{2k+1}}{2^{k+1}}=2^k\),然而我们要求所有的 \(h(s,t') \geq 2^k\),故所有的 \(h(s,t') = 2^k\)。
由于 \(cnt_{0,s} = cnt_{1,s} = cnt_{0,t} = cnt_{1,t} = 2^k\),故 \(h(s,t')=2^k\) 等价于满足 \(s_i = t'_i = 1\) 的位置 \(i\) 有 \(2^{k-1}\) 个,下面我们用新的方式刻画。
构造 \(F=\sum s_i x^i\),\(G=\sum t_{n-i-1} x^i\),故我们要求 \(F \times G \equiv 2^{k-1} \times \sum\limits_{i=0}^{2^{k+1}-1} x^i \pmod {x^{2^{k+1}}-1}\)。
我们将其化为 \(F \times G = 2^{k-1} \times \sum\limits_{i=0}^{2^{k+1}-1} x^i + C \times (x^{2^{k+1}}-1) = 2^{k-1} \times \sum\limits_{i=0}^{2^{k+1}-1} x^i + C \times (x-1) \times \sum\limits_{i=0}^{2^{k+1}-1} = \sum\limits_{i=0}^{2^{k+1}-1} \times ((x-1)C + 2^{k-1}) = ((x-1)C + 2^{k-1}) \times \prod\limits_{i=0}^k (x^{2^i} + 1)\)。
首先要求 \(x^{2^i} + 1 \mid F \times G\),其次要求 \(\dfrac{F \times G}{\prod\limits_{i=0}^k (x^{2^i} + 1)} = (x-1)C + 2^{k-1}\),即 \(\dfrac{F \times G}{\prod\limits_{i=0}^k (x^{2^i} + 1)} \equiv 2^{k-1} \pmod {x-1}\)。而一个多项式对 \((x-1)\) 取模后的结果为其带入 \(x=1\) 后的值,而 \(\dfrac{F(1) \times G(1)}{\prod\limits_{i=0}^k (1^{2^i} + 1)} = \dfrac{2^k \times 2^k}{2^{k+1}} = 2^{k-1}\),故第二个条件成立。
同时我们发现 \(x^{2^i}+1\) 在本题使用的数域下不可约,故只要求 \(x^{2^i} + 1 \mid F\) 或 \(x^{2^i} + 1 \mid G\)。
考虑对于 \(i \in [0,k]\),将 \(x\) 的次数按照模 \(2^i\) 分类,系数重组构成的新多项式是 \(x+1\) 的倍数,也就是带入 \(x=-1\) 后多项式的值为 \(0\)。
考虑建立 trie 树,对于为 \(1\) 的下标 \(i\) 从低到高将二进制位插入 trie,则上式等价于每个非叶节点左子树和右子树中的叶子个数相同,接下来对其 dp。
具体地,我们令 \(dp_{u,S,t}\) 表示在 \(u\) 的子树中,满足条件的 \(i\) 为 \(S\),选了 \(t\) 个叶子的方案数,这是容易 dp 的,可以获得 \(O(16^k)\) 的做法。
然而我们枚举 \(S\),复杂度可以变为 \(O(8^k)\),接下来我们精细分析一下复杂度。
发现每次需要左右相同,都会让有值的 gap 变成 \(2\) 倍,再加点小优化。

//Ad astra per aspera
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const long long mod=998244353;
int k;
char s[1<<13],t[1<<13];
int siz[1<<14],depth[1<<14],dp_len[1<<14];
long long ans[1<<13],ans_s[1<<13],ans_t[1<<13];
vector<long long> dp[1<<14];
void solve(){
int lst_S=-1;
for(int SS=0;SS<(1<<(k+1));SS++){
int S=0;
for(int i=0;i<=k;i++){
if(SS&(1<<i)){
S+=(1<<(k-i));
}
}
int p=0;
if(lst_S!=-1){
for(int i=0;i<=k;i++){
bool f_lst,f_now;
if(lst_S&(1<<i)){
f_lst=true;
}
else{
f_lst=false;
}
if(S&(1<<i)){
f_now=true;
}
else{
f_now=false;
}
if(f_lst!=f_now){
p=i;
break;
}
}
}
p=(1<<(k+1-p))-1;
dp[1][(1<<k)]=0;
for(int u=p;u>=1;u--){
if(S&(1<<depth[u])){
for(int j=0;j<=siz[u*2];j+=dp_len[u*2]){
dp[u][j*2]=dp[u*2][j]*dp[u*2+1][j];
dp[u][j*2]%=mod;
}
dp_len[u]=dp_len[u*2]*2;
}
else{
for(int i=0;i<=siz[u*2]+siz[u*2+1];i+=dp_len[u*2]){
dp[u][i]=0;
}
for(int i=0;i<=siz[u*2];i+=dp_len[u*2]){
for(int j=0;j<=siz[u*2+1];j+=dp_len[u*2+1]){
dp[u][i+j]+=dp[u*2][i]*dp[u*2+1][j];
dp[u][i+j]%=mod;
}
}
dp_len[u]=dp_len[u*2];
}
}
ans[S]=dp[1][(1<<k)];
lst_S=S;
}
for(int i=0;i<=k;i++){
for(int j=0;j<(1<<(k+1));j++){
if(j&(1<<i)){
ans[j-(1<<i)]=((ans[j-(1<<i)]-ans[j])%mod+mod)%mod;
}
}
}
}
int main(){
scanf("%d",&k);
for(int i=0;i<(1<<(k+1));i++){
cin>>s[i];
}
for(int i=0;i<(1<<(k+1));i++){
cin>>t[i];
}
for(int i=(1<<(k+2))-1;i>=1;i--){
if(i>=(1<<(k+1))){
siz[i]=1;
depth[i]=-1;
dp_len[i]=1;
}
else{
siz[i]=siz[i*2]+siz[i*2+1];
depth[i]=depth[i*2]+1;
}
for(int j=0;j<=siz[i];j++){
dp[i].push_back(0);
}
}
for(int i=(1<<(k+1));i<(1<<(k+2));i++){
int tmp=i-(1<<(k+1)),pre=0;
for(int j=0;j<=k;j++){
if(tmp&(1<<j)){
pre+=(1<<(k-j));
}
}
if(s[pre]=='0'){
dp[i][0]=1;
dp[i][1]=0;
}
if(s[pre]=='1'){
dp[i][0]=0;
dp[i][1]=1;
}
if(s[pre]=='?'){
dp[i][0]=1;
dp[i][1]=1;
}
}
solve();
for(int i=0;i<(1<<(k+1));i++){
ans_s[i]=ans[i];
}
for(int i=(1<<(k+1));i<(1<<(k+2));i++){
int tmp=i-(1<<(k+1)),pre=0;
for(int j=0;j<=k;j++){
if(tmp&(1<<j)){
pre+=(1<<(k-j));
}
}
if(t[pre]=='0'){
dp[i][0]=1;
dp[i][1]=0;
}
if(t[pre]=='1'){
dp[i][0]=0;
dp[i][1]=1;
}
if(t[pre]=='?'){
dp[i][0]=1;
dp[i][1]=1;
}
}
solve();
for(int i=0;i<(1<<(k+1));i++){
ans_t[i]=ans[i];
}
long long final_ans=0;
for(int i_s=0;i_s<(1<<(k+1));i_s++){
for(int i_t=0;i_t<(1<<(k+1));i_t++){
if((i_s|i_t)==(1<<(k+1))-1){
final_ans+=ans_s[i_s]*ans_t[i_t]%mod;
final_ans%=mod;
}
}
}
printf("%lld\n",final_ans);
return 0;
}

浙公网安备 33010602011771号