不匹配度就是異或後數1的個數。可以壓位最佳化一下,需要對於任意為開始,每 16 16 壓一起。預先處理 216 2^{16} 以內的數中1的個數。
這樣可以最佳化到 O(n∗Q/16) O(n*Q/16),是可以過的。
對於最後1分的包,考慮答案為 ∑(S1i−S2j)2=∑S12i+∑S22i−2∑S1i∗S2j \sum (S1_i-S2_j)^2=\sum S1_i^2+\sum S2_i^2-2\sum S1_i*S2_j
只需求 Fi=∑i+N−1j=iS1j∗S2j F_i=\sum_{j=i}^{i+N-1} S1_j*S2_j,然後變形一下,把 S1 S1 反一下:
Fi=∑j=0i+n−1S1′i−j∗S2j F_i=\sum_{j=0}^{i+n-1} S1^{'}_{i-j}*S2_j 然後 FFT FFT。
#include<cstdio>#include<cmath>#include<cstring>#include<bitset>#include<algorithm>using namespace std;const int maxn=2000005;inline char gc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline int getint(){ char ch=gc(); int res=0; while(!('0'<=ch&&ch<='9')) ch=gc(); while('0'<=ch&&ch<='9') res=(res<<1)+(res<<3)+ch-'0', ch=gc(); return res;}int n,m,Q,last_ans,b1[18][maxn],b2[18][maxn],cnt[(1<<16)+5],S1[maxn],S2[maxn],sum1,sum2[maxn];int Get(int a[],int L,int R){ int res=0; for(int i=L;i<=R;i++) res|=(a[i]<<i-L); return res;}void Pre(){ for(int i=0;i+15<=n;i+=16) b1[0][i/16]=Get(S1,i,i+15); for(int j=1;j<=15;j++) for(int i=j;i+15<=n;i+=16) b1[j][i/16]=b1[j-1][i/16]>>1|(S1[i+15]<<15); for(int i=0;i+15<=m;i+=16) b2[0][i/16]=Get(S2,i,i+15); for(int j=1;j<=15;j++) for(int i=j;i+15<=m;i+=16) b2[j][i/16]=b2[j-1][i/16]>>1|(S2[i+15]<<15); for(int i=1;i<=(1<<16)-1;i++){ int t=i; do cnt[i]+=t&1, t>>=1; while(t); }}int Solve(