关于匹配串T在模式串中出现的位置不一定按顺序……只需要保证位置差不过k。
于是……FFT板题
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
const double Pi=acos(-1);
int ch2int(char c) {
if(c=='A') return 1;
if(c=='T') return 2;
if(c=='G') return 3;
if(c=='C') return 4;
return 0;
}
char str[N];
int n,m,K,ans,s[N],t[N],SUM[N];
int p,pL,rev[N<<1];
struct cplx {
double x,y;
cplx(){}
cplx(double x,double y):x(x),y(y){}
cplx operator+(const cplx&d) {return cplx(x+d.x,y+d.y);}
cplx operator-(const cplx&d) {return cplx(x-d.x,y-d.y);}
cplx operator*(const cplx&d) {return cplx(x*d.x-y*d.y,x*d.y+y*d.x);}
} a[N<<1],b[N<<1];
void fft(cplx*a,int type) {
for(int i=0; i<p; ++i) if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int m=1; m<p; m<<=1) {
cplx wm(cos(Pi/m),type*sin(Pi/m));
for(int i=0; i<p; i+=(m<<1)) {
cplx w(1,0),tmp;
for(int j=0; j<m; ++j,w=w*wm) {
tmp=w*a[m+i+j];
a[m+i+j]=a[i+j]-tmp;
a[i+j]=a[i+j]+tmp;
}
}
}
if(type<0) for(int i=0; i<p; ++i) a[i].x/=p;
}
void solve(int c) {
memset(a,0,sizeof a);
memset(b,0,sizeof b);
for(int i=0,p=-inf; i<n; ++i) {
if(s[i]==c) p=i;
if(i-p<=K) a[i].x=1;
}
for(int i=n-1,p=inf; ~i; --i) {
if(s[i]==c) p=i;
if(p-i<=K) a[i].x=1;
}
for(int i=0; i<m; ++i) if(t[i]==c) b[m-i-1].x=1;
fft(a,1); fft(b,1);
for(int i=0; i<p; ++i) a[i]=a[i]*b[i];
fft(a,-1);
for(int i=0; i<n; ++i) SUM[i]+=int(a[i].x+0.5);
}
int main() {
scanf("%d%d%d",&n,&m,&K);
scanf("%s",str); for(int i=0; i<n; ++i) s[i]=ch2int(str[i]);
scanf("%s",str); for(int i=0; i<n; ++i) t[i]=ch2int(str[i]);
for(p=1,pL=0; p<(n+m-1); p<<=1,pL++);
for(int i=0; i<p; ++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(pL-1));
for(int i=1; i<=4; ++i) solve(i);
for(int i=0; i<n; ++i) ans+=(SUM[i]>=m);
printf("%d
",ans);
return 0;
}