zoukankan      html  css  js  c++  java
  • CF528D Fuzzy Search (生成函数+FFT)

    题目传送门

    题目大意:给你两个只包含A,G,C,T的字符串$S$,$T$,$S$长$T$短,按照如下图方式匹配 解释不明白直接上图

    能容错的距离不超过$K$,求能$T$被匹配上的次数

    $S$串同一个位置可以被$T$的不同位置匹配多次

    对4种字符分别处理,假设我们现在只讨论字符A

    对于字符串AGCAATTCAT,字符A的生成函数就是1001100010

    题目要求距离不超过K就能匹配,把周围距离不超过$K$的位置都变成1,形成一个新串$S'$

    $S$  1001100010

    $S'$ 1111110111

    只要$T$和$S'$的某个子串匹配时,子串中1的个数 不少于 $T$串中1的个数,就表明$T$串能被匹配上

    把$T$串反转,再进行卷积,每一位都分4钟情况讨论即可

      1 #include <cmath>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define N1 (1<<19)
      6 #define il inline
      7 #define dd double
      8 #define ld long double
      9 #define ll long long
     10 using namespace std;
     11 
     12 int gint()
     13 {
     14     int ret=0,fh=1;char c=getchar();
     15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
     16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
     17     return ret*fh;
     18 }
     19 int idx(char c)
     20 {
     21     if(c=='A') return 0;
     22     if(c=='C') return 1;
     23     if(c=='G') return 2;
     24     if(c=='T') return 3;
     25 }
     26 const int inf=0x3f3f3f3f;
     27 
     28 namespace FFT{
     29 
     30 const dd pi=acos(-1);
     31 struct cp{
     32 dd x,y;
     33 friend cp operator + (const cp &s1,const cp &s2){ return (cp){s1.x+s2.x,s1.y+s2.y}; }
     34 friend cp operator - (const cp &s1,const cp &s2){ return (cp){s1.x-s2.x,s1.y-s2.y}; }
     35 friend cp operator * (const cp &s1,const cp &s2){ return (cp){s1.x*s2.x-s1.y*s2.y,s1.y*s2.x+s1.x*s2.y}; }
     36 }a[N1],b[N1],c[N1];
     37 int r[N1];
     38 void FFT(cp *s,int len,int type)
     39 {
     40     int i,j,k; cp wn,w,t;
     41     for(i=0;i<len;i++) if(i<r[i]) swap(s[i],s[r[i]]);
     42     for(k=2;k<=len;k<<=1)
     43     {
     44         wn=(cp){cos(2.0*type*pi/k),sin(2.0*type*pi/k)};
     45         for(i=0;i<len;i+=k)
     46         {
     47             w=(cp){1,0};
     48             for(j=0;j<(k>>1);j++,w=w*wn)
     49             {
     50                 t=w*s[i+j+(k>>1)];
     51                 s[i+j+(k>>1)]=s[i+j]-t;
     52                 s[i+j]=s[i+j]+t;
     53             }
     54         }
     55     }
     56 }
     57 void Main(int len,int L)
     58 {
     59     int i;
     60     for(i=0;i<len;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1));
     61     FFT(a,len,1); FFT(b,len,1);
     62     for(i=0;i<len;i++) c[i]=a[i]*b[i];
     63     FFT(c,len,-1);
     64     for(i=0;i<len;i++) c[i].x/=len;
     65 }
     66 void init()
     67 {
     68     memset(a,0,sizeof(a));
     69     memset(b,0,sizeof(b));
     70 }
     71 
     72 };
     73 using FFT::a; using FFT::b; using FFT::c;
     74 
     75 int s[N1],t[N1],nt[N1],n,m,K,len,L;
     76 char S[N1],T[N1];
     77 void solve(int p)
     78 {
     79     FFT::init();
     80     int i,j,k,num=0;
     81     for(i=0,k=0;i<n;i++) if(s[i]==p) 
     82         for(k=max(k,i-K);k<=min(n,i+K);k++) a[k].x=1;
     83     for(i=n-1,k=n-1;i;i--) if(s[i]==p) 
     84         for(k=min(k,i+K);k>=max(0,i-K);k--) a[k].x=1;
     85     for(i=0;i<m;i++) if(t[i]==p) b[m-i-1].x=1,num++;
     86     FFT::Main(len,L);
     87     for(i=0;i<n;i++) if((int)(c[i].x+0.1)<num) nt[i]=1;
     88 }
     89 
     90 int main()
     91 {
     92     int i,j,ans=0; 
     93     scanf("%d%d%d",&n,&m,&K);
     94     scanf("%s",S); scanf("%s",T);
     95     for(i=0;i<n;i++) s[i]=idx(S[i]);
     96     for(i=0;i<m;i++) t[i]=idx(T[i]);
     97     for(len=1,L=0;len<(n+m-1);len<<=1,L++);
     98     solve(0);
     99     solve(1);
    100     solve(2);
    101     solve(3);
    102     for(i=0;i<n;i++) if(!nt[i]) ans++;
    103     printf("%d
    ",ans);
    104     return 0;
    105 
    106 }  
  • 相关阅读:

    链表
    Codeforces 1290A/1291C
    Codeforces 1291B
    Codeforces 1291A
    Codeforces 1295C
    Codeforces 1295B
    ZJNU 2356
    ZJNU 2354
    ZJNU 2353
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10353778.html
Copyright © 2011-2022 走看看