• 快速傅里叶变换(FFT):COGS 2216. 你猜是不是KMP


    2216. 你猜是不是KMP

    ★★★☆   输入文件:guess.in   输出文件:guess.out   简单对比
    时间限制:1 s   内存限制:256 MB

    【题目描述】

      XX在玩两个串的游戏。首先,他拿出了两个字符串 S 和 T,XX想知道 T在 S 中出现了几次,分别在哪些位置出现。注意 T 中可能有“?”字符,这个字符可以匹配任何字符。

    【输入格式】

      两行两个字符串,分别代表 S 和 T

    【输出格式】

      第一行一个正整数 k,表示 T 在 S 中出现了几次。

      接下来 k 行正整数,

      分别代表 T 每次在 S 中出现的开始位置。按照从小到大

      的顺序输出,S 下标从 0 开始。

    【样例输入】

      ababcadaca

      a?a

    【样例输出】

      3

      0

      5

      7

    【提示】

      对于 10%的数据, S 和 T 的长度不超过 100

      对于另外 20%的数据,T 中无“?”

      对于 100%的数据,S 长度不超过 10^5,T 长度不会超过 S。S 中只包含小写

      字母,T 中只包含小写字母和“?”

    【来源】

      经典题目

      

      这道题咩,是FFT哦,咳咳……

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <cmath>
      5 using namespace std;
      6 const int maxn=400010;
      7 const double PI=acos(-1.0);
      8 char s[maxn],t[maxn];
      9 int a[maxn],b[maxn];
     10 struct complex{
     11     double r,i;
     12     complex(double r_=0.0,double i_=0.0){
     13         r=r_;i=i_;
     14     }
     15     complex operator +(complex a){
     16         return complex(r+a.r,i+a.i);
     17     }
     18     complex operator -(complex a){
     19         return complex(r-a.r,i-a.i);
     20     }
     21     complex operator *(complex a){
     22         return complex(r*a.r-i*a.i,r*a.i+i*a.r);
     23     }
     24 };
     25 complex A[maxn],B[maxn],C[maxn],D[maxn],E[maxn];
     26 
     27 void Rader(complex *a,int len){
     28     int k;
     29     for(int i=1,j=len>>1;i<len-1;i++){
     30         if(i<j)swap(a[i],a[j]);
     31         k=len>>1;
     32         while(j>=k){
     33             j-=k;
     34             k>>=1;
     35         }
     36         j+=k;
     37     }        
     38 }
     39 
     40 void FFT(complex *a,int len,int on){
     41     Rader(a,len);
     42     for(int h=2;h<=len;h<<=1){
     43         complex wn(cos(-on*PI*2.0/h),sin(-on*PI*2.0/h));
     44         for(int j=0;j<len;j+=h){
     45             complex w(1,0);
     46             for(int k=j;k<j+(h>>1);k++){
     47                 complex u=a[k];
     48                 complex v=a[k+(h>>1)]*w;
     49                 a[k]=u+v;
     50                 a[k+(h>>1)]=u-v;
     51                 w=w*wn;
     52             }
     53         }
     54     }
     55     if(on==-1)
     56         for(int i=0;i<len;i++)
     57             a[i].r/=len;    
     58 }
     59 int ans[maxn],tot;
     60 int main(){
     61     freopen("guess.in","r",stdin);
     62     freopen("guess.out","w",stdout);
     63     scanf("%s%s",s,t);
     64     int lens=strlen(s);
     65     int lent=strlen(t);
     66     for(int i=0;i<lens;i++)
     67         a[i]=s[i]-'a'+1;
     68     for(int i=0;i<lent;i++){
     69         if(t[i]=='?')
     70             b[lent-i-1]=0;
     71         else
     72             b[lent-i-1]=t[i]-'a'+1;    
     73     }
     74     
     75     int len=1;
     76     while(len<=lens+lent)len<<=1;
     77     
     78     for(int i=0;i<lens;i++)A[i]=complex(1.0,0);
     79     for(int i=0;i<lent;i++)B[i]=complex(1.0*b[i]*b[i]*b[i],0);
     80     FFT(A,len,1);FFT(B,len,1);
     81     for(int i=0;i<len;i++)C[i]=A[i]*B[i];
     82     FFT(C,len,-1);    
     83     
     84     memset(A,0,sizeof(A));
     85     memset(B,0,sizeof(B));
     86     for(int i=0;i<lens;i++)A[i]=complex(2.0*a[i],0);
     87     for(int i=0;i<lent;i++)B[i]=complex(1.0*b[i]*b[i],0);
     88     FFT(A,len,1);FFT(B,len,1);
     89     for(int i=0;i<len;i++)D[i]=A[i]*B[i];
     90     FFT(D,len,-1);
     91         
     92     memset(A,0,sizeof(A));
     93     memset(B,0,sizeof(B));
     94     for(int i=0;i<lens;i++)A[i]=complex(1.0*a[i]*a[i],0);
     95     for(int i=0;i<lent;i++)B[i]=complex(1.0*b[i],0);
     96     FFT(A,len,1);FFT(B,len,1);
     97     for(int i=0;i<len;i++)E[i]=A[i]*B[i];
     98     FFT(E,len,-1);
     99     
    100     for(int i=lent-1;i<lens;i++)
    101         if(fabs(C[i].r-D[i].r+E[i].r)<1e-5)
    102             ans[++tot]=i-lent+1;
    103         
    104     printf("%d
    ",tot);
    105     for(int i=1;i<=tot;i++)
    106         printf("%d
    ",ans[i]);        
    107     return 0;
    108 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    PHP面试题遇到的几个坑。...面壁ing
    Java基础- super 和 this 解析
    openStack use
    ceph伦理概念
    openstack core components use 总结
    current imporant Posts
    openNebula rgister img instance vms error collections
    openStack images概念及维护
    Error copying image in the datastore: Not allowed to copy image file
    OpenNebula openldap集成
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5403233.html
Copyright © 2020-2023  润新知