题意:
解法:
设 s [ 0 , n ] , t [ 0 , m ] . 令 f ( x ) = ∑ i = 0 m ( s [ x + i ] − t [ i ] ) 2 , 显 然 f ( x ) 是 以 s [ x ] 为 开 头 , 与 t 串 匹 配 需 要 的 修 改 位 数 . 将 式 子 展 开 可 得 : f ( x ) = ∑ i = 0 m s [ x + i ] 2 + ∑ i = 0 m t [ i ] 2 − 2 ∑ i = 0 m s [ x + i ] ∗ t [ i ] . 前 两 项 用 前 缀 和 就 能 计 算 出 来 , 第 三 项 g ( x ) = ∑ i = 0 m s [ x + i ] ∗ t [ i ] , 将 t 串 反 转 , 那 么 式 子 变 为 : g ( x ) = ∑ i = 0 m s [ x + i ] ∗ t [ m − i ] 变 成 了 卷 积 形 式 , 可 以 用 F F T 或 者 N T T 计 算 g ( x ) = s ( ) 和 t ( ) 卷 积 结 果 的 第 x + m 项 设s[0,n],t[0,m].\\ 令f(x)=\sum_{i=0}^{m}(s[x+i]-t[i])^2,\\ 显然f(x)是以s[x]为开头,与t串匹配需要的修改位数.\\ 将式子展开可得:\\ f(x)=\sum_{i=0}^{m}s[x+i]^2+\sum_{i=0}^{m}t[i]^2-2\sum_{i=0}^{m}s[x+i]*t[i].\\ 前两项用前缀和就能计算出来,\\ 第三项g(x)=\sum_{i=0}^{m}s[x+i]*t[i],\\ 将t串反转,那么式子变为:\\ g(x)=\sum_{i=0}^{m}s[x+i]*t[m-i]\\ 变成了卷积形式,可以用FFT或者NTT计算\\ g(x)=s()和t()卷积结果的第x+m项 设s[0,n],t[0,m].令f(x)=i=0∑m(s[x+i]−t[i])2,显然f(x)是以s[x]为开头,与t串匹配需要的修改位数.将式子展开可得:f(x)=i=0∑ms[x+i]2+i=0∑mt[i]2−2i=0∑ms[x+i]∗t[i].前两项用前缀和就能计算出来,第三项g(x)=i=0∑ms[x+i]∗t[i],将t串反转,那么式子变为:g(x)=i=0∑ms[x+i]∗t[m−i]变成了卷积形式,可以用FFT或者NTT计算g(x)=s()和t()卷积结果的第x+m项
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=4e6+5;
const int mod=998244353;
// const int mod=1004535809;
// const int mod=469762049;
const int G=3;
int rev[maxm];
char s[maxm];
int a[maxm];
int b[maxm];
int sum1[maxm];
int sum2[maxm];
int sum3[maxm];
int n,m;
int ppow(int a,int b,int mod){
int ans=1%mod;a%=mod;
while(b){
if(b&1)ans=1ll*ans*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return ans;
}
void ntt(int a[],int len,int on){
for(int i=0;i<len;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int i=1;i<len;i<<=1){
int wn=ppow(G,(mod-1)/(i<<1),mod);
if(on==-1)wn=ppow(wn,mod-2,mod);
for(int j=0;j<len;j+=(i<<1)){
int w=1;
for(int k=0;k<i;k++){
int x=a[j+k],y=1ll*w*a[i+j+k]%mod;
a[j+k]=((1ll*x+y)%mod+mod)%mod;
a[i+j+k]=(1ll*x-y+mod)%mod;
w=1ll*w*wn%mod;
}
}
}
if(on==-1){
int inv=ppow(len,mod-2,mod);
for(int i=0;i<len;i++)a[i]=1ll*a[i]*inv%mod;
}
}
signed main(){
//
scanf("%s",s);
n=strlen(s);n--;
for(int i=0;i<=n;i++)a[i]=s[i]-'0';
sum1[0]=a[0]*a[0];
for(int i=1;i<=n;i++)sum1[i]=sum1[i-1]+a[i]*a[i];
//
scanf("%s",s);
m=strlen(s);m--;
for(int i=0;i<=m;i++)b[i]=s[i]-'0';
sum2[0]=b[0]*b[0];
for(int i=1;i<=m;i++)sum2[i]=sum2[i-1]+b[i]*b[i];
//
reverse(b,b+m+1);
int len=1,l=0;
while(len<=m+n)len<<=1,l++;
for(int i=0;i<len;i++){
rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
}
ntt(a,len,1);
ntt(b,len,1);
for(int i=0;i<len;i++)a[i]=1ll*a[i]*b[i]%mod;
ntt(a,len,-1);
len=n+m;
for(int i=0;i<=n+m;i++){
sum3[i]=a[i];
}
int ans=1e9;
for(int i=0;i<=n-(m+1)+1;i++){
int t=0;
t+=sum1[i+m]-(i==0?0:sum1[i-1]);
t+=sum2[m];
t-=2*sum3[i+m];
ans=min(ans,t);
}
cout<<ans<<endl;
return 0;
}