codeforces 528D Fuzzy Search

链接:codeforces 528D

正解:$FFT$。

很多字符串匹配的问题都可以用$FFT$来实现。

这道题是要求在左边和右边$k$个字符内有字符和模式串匹配,那么用$kmp$是显然不行的。我们考虑把模式串翻转一下。因为只有4个字符,所以每个字符我们分开考虑。然后对于母串,如果在给定范围内有当前字符,这个位置就赋值为1;对于模式串,如果当前位置是当前字符,这个位置就赋为1。然后我们对这两个多项式做一下卷积,记录$Ans$,最后4种字符的$Ans$求和如果等于$m$,那么这个位置就是匹配的。

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <complex>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <cstdio>
 8 #include <cmath>
 9 #define pi acos(-1)
10 #define inf (1<<29)
11 #define NN (1000010)
12 #define il inline
13 #define RG register
14 #define ll long long
15 #define C complex <double>
16 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
17 
18 using namespace std;
19 
20 int ans[NN],rev[NN],n,m,k,N,M,lg,pos,res;
21 char s[NN],t[NN],fg[5]="AGCT";
22 C a[NN],b[NN];
23 
24 il int gi(){
25     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
26     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
27 }
28 
29 il void fft(C *a,RG int n,RG int f){
30     for (RG int i=0;i<n;++i) if (i<rev[i]) swap(a[i],a[rev[i]]);
31     for (RG int i=1;i<n;i<<=1){
32     C wn(cos(pi/i),sin(f*pi/i)),x,y;
33     for (RG int j=0;j<n;j+=(i<<1)){
34         C w(1,0);
35         for (RG int k=0;k<i;++k,w*=wn){
36         x=a[j+k],y=w*a[j+i+k];
37         a[j+k]=x+y,a[j+i+k]=x-y;
38         }
39     }
40     }
41     return;
42 }
43 
44 il void work(){
45     n=gi(),m=gi(),k=gi(); scanf("%s%s",s,t); reverse(t,t+m);
46     M=n+m; for (N=1;N<=M;N<<=1) lg++;
47     for (RG int i=0;i<=N;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
48     for (RG int p=0;p<4;++p){
49     memset(a,0,sizeof(a)),memset(b,0,sizeof(b));
50     pos=-inf;
51     for (RG int i=0;i<n;++i){
52         if (s[i]==fg[p]) pos=i;
53         if (i-pos<=k) a[i]=1;
54     }
55     pos=inf;
56     for (RG int i=n-1;i>=0;--i){
57         if (s[i]==fg[p]) pos=i;
58         if (pos-i<=k) a[i]=1;
59     }
60     for (RG int i=0;i<m;++i) if (t[i]==fg[p]) b[i]=1;
61     fft(a,N,1),fft(b,N,1); for (RG int i=0;i<N;++i) a[i]*=b[i];
62     fft(a,N,-1); for (RG int i=0;i<N;++i) ans[i]+=(int)(a[i].real()/N+0.5);
63     }
64     for (RG int i=0;i<N;++i) if (ans[i]==m) res++; printf("%d",res); return;
65 }
66 
67 int main(){
68     File("fuzzy");
69     work();
70     return 0;
71 }
原文地址:https://www.cnblogs.com/wfj2048/p/6570569.html