codeforces round# 296 (div1 D)(bitmasks)

本题目用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;
}


你可能感兴趣的:(codeforces round# 296 (div1 D)(bitmasks))