本题目用bitset很容易搞定,也可用fft可惜不会:
首先,统计出每个位置是否可以匹配特定字母,那么对于0 - n-1这些位置,只有当以位置为首位,且可以匹配模板串首位时,才有可能匹配,必须能在该位置的下一位匹配到模板串的第二位。用bitset即可实现。
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <set> #include <map> #include <string> #include <list> #include <cstdlib> #include <queue> #include <stack> #include <cmath> #include <bitset> #include <cassert> #define ALL(a) a.begin(), a.end() #define clr(a, x) memset(a, x, sizeof a) #define X first #define Y second #define pb push_back #define lowbit(x) (x&(-x)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define rep1(i,x,y) for(int i=x;i<=y;i++) #define rep(i,n) for(int i=0;i<(int)n;i++) using namespace std; const double eps = 1e-10; typedef long long LL; typedef long long ll; typedef pair<int, int> pii; const int oo =0x3f3f3f3f; const ll inf = 1e15; const char* ss="AGCT"; int id(char c){rep(i,4)if(ss[i]==c) return i;} const int N = 2e5 + 100; int n,m,k; char s1[N],s2[N]; int cnt[N][4]={0}; bitset<N> hav[4],ans; int main() { scanf("%d %d %d",&n,&m,&k); scanf("%s %s",s1,s2); rep(i,n){ cnt[max(0,i-k)][id(s1[i])]++,cnt[min(n,i+k+1)][id(s1[i])]--; } // 使用了区间累加计数法 rep(i,n){ rep(j,4) cnt[i][j]=cnt[i-1][j]+cnt[i][j],hav[j][i]=!!cnt[i][j]; ans[i]=1; } rep(i,m){ ans &= (hav[id(s2[i])]>>i); } int aa=0; rep(i,n) aa+=ans[i]; cout<<aa<<endl; return 0; }