看起来就有点像fft处理带通配符的字符串匹配问题。
AGCT四种字符分类讨论。例如当前匹配A字符,对于S串,把能匹配A的位置记为1,否则为0;对于T串,把A的位置记为1,否则为0。然后还是像通配符问题一样反转T串,用fft加速。这样,对于某一匹配起始位置,能成功匹配的A就会对该位置提供1的贡献。四种字符都做完后,贡献和等于T串长度就位置就是匹配成功的的位置了。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<complex>
#include<algorithm>
#define cp complex<double>
using namespace std;
const int N=200010,M=525000;
const double PI=acos(-1);
char s1[N],s2[N];
int n,n1,n2,k,flag[N],ans,rev[M],lim,tot[N];
cp omg[M],inv[M],a1[M],b1[M];
inline void fft(cp* a,cp* w){
for(int i=0;i<n;++i)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int m=1,l=2;l<=n;m=l,l<<=1){
for(int i=0;i<n;i+=l)
for(int j=0;j<m;++j){cp tmp=w[n/l*j]*a[i+j+m];a[i+j+m]=a[i+j]-tmp,a[i+j]+=tmp;}
}
}
int main(){
scanf("%d%d%d",&n1,&n2,&k),scanf("%s",s1),scanf("%s",s2);
n=1;while(n<n1+n2)n<<=1;
lim=0;while((1<<lim)<n)++lim;
for(int t=0,i=0;i<n;++i,t=0){
for(int j=0;j<lim;++j)if((1<<j)&i)t|=1<<(lim-j-1);
rev[i]=t,rev[t]=i;
}
for(int i=0;i<n;++i)omg[i]=cp(cos(2*PI*i/n),sin(2*PI*i/n)),inv[i]=conj(omg[i]);
memset(tot,0,sizeof tot);
//A
for(int i=0;i<n;++i)a1[i]=cp(0,0);
for(int j,i=0;i<n1;++i)
if(s1[i]=='A'){
a1[i].real(1),j=i-1;
while(i-j<=k&&j>=0&&s1[j]!='A'&&a1[j].real()==0)a1[j].real(1),--j;
j=i+1;
while(j-i<=k&&j<n1&&s1[j]!='A')a1[j].real(1),++j;
}
for(int i=0;i<n2;++i)b1[n2-i-1]=(s2[i]=='A')?cp(1,0):cp(0,0);
for(int i=n2;i<n;++i)b1[i]=cp(0,0);
fft(a1,omg),fft(b1,omg);
for(int i=0;i<n;++i)a1[i]*=b1[i];
fft(a1,inv);
for(int i=n2-1;i<n1;++i)tot[i-n2+1]+=(int)(a1[i].real()/n+0.5);
//G
for(int i=0;i<n;++i)a1[i]=cp(0,0);
for(int j,i=0;i<n1;++i)
if(s1[i]=='G'){
a1[i].real(1),j=i-1;
while(i-j<=k&&j>=0&&s1[j]!='G'&&a1[j].real()==0)a1[j].real(1),--j;
j=i+1;
while(j-i<=k&&j<n1&&s1[j]!='G')a1[j].real(1),++j;
}
for(int i=0;i<n2;++i)b1[n2-i-1]=(s2[i]=='G')?cp(1,0):cp(0,0);
for(int i=n2;i<n;++i)b1[i]=cp(0,0);
fft(a1,omg),fft(b1,omg);
for(int i=0;i<n;++i)a1[i]*=b1[i];
fft(a1,inv);
for(int i=n2-1;i<n1;++i)tot[i-n2+1]+=(int)(a1[i].real()/n+0.5);
//C
for(int i=0;i<n;++i)a1[i]=cp(0,0);
for(int j,i=0;i<n1;++i)
if(s1[i]=='C'){
a1[i].real(1),j=i-1;
while(i-j<=k&&j>=0&&s1[j]!='C'&&a1[j].real()==0)a1[j].real(1),--j;
j=i+1;
while(j-i<=k&&j<n1&&s1[j]!='C')a1[j].real(1),++j;
}
for(int i=0;i<n2;++i)b1[n2-i-1]=(s2[i]=='C')?cp(1,0):cp(0,0);
for(int i=n2;i<n;++i)b1[i]=cp(0,0);
fft(a1,omg),fft(b1,omg);
for(int i=0;i<n;++i)a1[i]*=b1[i];
fft(a1,inv);
for(int i=n2-1;i<n1;++i)tot[i-n2+1]+=(int)(a1[i].real()/n+0.5);
//T
for(int i=0;i<n;++i)a1[i]=cp(0,0);
for(int j,i=0;i<n1;++i)
if(s1[i]=='T'){
a1[i].real(1),j=i-1;
while(i-j<=k&&j>=0&&s1[j]!='T'&&a1[j].real()==0)a1[j].real(1),--j;
j=i+1;
while(j-i<=k&&j<n1&&s1[j]!='T')a1[j].real(1),++j;
}
for(int i=0;i<n2;++i)b1[n2-i-1]=(s2[i]=='T')?cp(1,0):cp(0,0);
for(int i=n2;i<n;++i)b1[i]=cp(0,0);
fft(a1,omg),fft(b1,omg);
for(int i=0;i<n;++i)a1[i]*=b1[i];
fft(a1,inv);
for(int i=n2-1;i<n1;++i)tot[i-n2+1]+=(int)(a1[i].real()/n+0.5);
ans=0;
for(int i=0;i<=n1-n2;++i)if(tot[i]==n2)++ans;
printf("%d",ans);
return 0;
}