• 【bzoj4259】 残缺的字符串 FFT


    又是一道FFT套路题

    思路可以参考bzoj4503,题解

    我们对串S和串T中出现的*处全部赋值为0。

    反正最终的差异度式子大概就是

    $C[i]=sum_{j=0}^{|T|-1}S[i+j]T[j](S[i+j]-T[j])^2$

    然后和上一题一样的展开方式,将T串reverse一下做FFT再统计下即可。

    然后这题卡常,FFT的长度是100W,所以用NTT会被卡常(我就T了)

    然后就没了

     1 #include<bits/stdc++.h>
     2 #define PI acos(-1)
     3 #define zero(x) (fabs(x)<0.5)
     4 #define M 1<<20
     5 using namespace std;
     6 struct cp{
     7     double r,i;
     8     cp(){r=i=0;} cp(int x){r=x; i=0;}
     9     cp(double rr,double ii){r=rr;i=ii;}
    10     friend cp operator +(cp a,cp b){return cp(a.r+b.r,a.i+b.i);}
    11     friend cp operator -(cp a,cp b){return cp(a.r-b.r,a.i-b.i);}
    12     friend cp operator *(cp a,cp b){return cp(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);}
    13 };
    14 
    15 cp a[M]={0},aa[M]={0},aaa[M]={0};
    16 cp b[M]={0},bb[M]={0},bbb[M]={0};
    17 int n; cp ans[M]={0};
    18 
    19 void change(cp a[],int n){
    20     for(int i=0,j=0;i<n-1;i++){
    21         if(i<j) swap(a[i],a[j]);
    22         int k=n>>1; 
    23         while(j>=k) j-=k,k>>=1;
    24         j+=k;
    25     }
    26 }
    27 void FFT(cp a[],int n,int on){
    28     change(a,n);
    29     for(int h=2;h<=n;h<<=1){
    30         cp wn=cp(cos(2*PI/h),on*sin(2*PI/h));
    31         for(int j=0;j<n;j+=h){
    32             cp w=cp(1,0);
    33             for(int k=j;k<j+(h>>1);k++){
    34                 cp u=a[k],t=w*a[k+(h>>1)];
    35                 a[k]=u+t; 
    36                 a[k+(h>>1)]=u-t;
    37                 w=w*wn;
    38             }
    39         }
    40     }
    41     if(on==-1) for(int i=0;i<n;i++) a[i].r/=n;
    42 }
    43 
    44 char s[M]={0},c[M]={0};
    45 int lens,lenc,len=1;
    46 int main(){
    47     scanf("%d%d",&lens,&lenc); 
    48     scanf("%s%s",c,s);
    49     lens=strlen(s); lenc=strlen(c);
    50     while(len<lens+lenc) len<<=1;
    51     reverse(c,c+lenc);
    52     for(int i=0;i<lens;i++) a[i]=(s[i]=='*'?0:s[i]-'a'+1),aa[i]=a[i]*a[i],aaa[i]=aa[i]*a[i];
    53     for(int i=0;i<lenc;i++) b[i]=(c[i]=='*'?0:c[i]-'a'+1),bb[i]=b[i]*b[i],bbb[i]=bb[i]*b[i];
    54     FFT(a,len,1); FFT(aa,len,1); FFT(aaa,len,1);
    55     FFT(b,len,1); FFT(bb,len,1); FFT(bbb,len,1);
    56     for(int i=0;i<len;i++) ans[i]=aaa[i]*b[i]-2*aa[i]*bb[i]+a[i]*bbb[i];
    57     FFT(ans,len,-1);
    58     int sum=0;
    59     for(int i=lenc-1;i<lens;i++) 
    60     if(zero(ans[i].r)) sum++;
    61     cout<<sum<<endl;
    62     for(int i=lenc-1;i<lens;i++)
    63     if(zero(ans[i].r)) printf("%d ",i-lenc+2);
    64 }
  • 相关阅读:
    IOS回调机制总结
    2.25~当svn服务器ip地址变了怎么办?
    ubuntu硬件信息,内存DDR详细信息
    关于JS相等比较算法(==)的原理
    ubuntu更改鼠标滚轮方向为自然方向(运动方向和滚轮滚动方向一致)
    C#模拟js的Json对象创建,操作
    关于json返回日期格式化的解决方案
    js定时器 timer
    ubuntu GUI界面复制文件没权限的解决方案
    CodeSmith 模板
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/9368016.html
Copyright © 2020-2023  润新知