zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Sum Root to Leaf Numbers
    Sum Root to Leaf Numbers
    Sort Colors
    Partition List
    Binary Tree Inorder Traversal
    Binary Tree Postorder Traversal
    Remove Duplicates from Sorted List II
    Remove Duplicates from Sorted List
    Search a 2D Matrix
    leetcode221
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6570569.html
Copyright © 2011-2022 走看看