• BZOJ 4259 FFT


    思路:

    为什么好多字符串的题都可以用FFT啊....

    我们其实是要判断$Sigma (a[i]-b[i])^2*a[i]*b[i]==0$

    那就把a串翻转过来 把 上式展开

    大力做几遍FFT就好啦~

    //By SiriusRen
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define double long double
    const double pi=acos(-1);
    const int N=666666;
    int nn,mm,n,L,R[N],all;
    struct Complex{
        double x,y;Complex(){}
        Complex(double X,double Y){x=X,y=Y;}
    }A[N],B[N],ans[N];
    Complex operator+(Complex a,Complex b){return Complex(a.x+b.x,a.y+b.y);}
    Complex operator-(Complex a,Complex b){return Complex(a.x-b.x,a.y-b.y);}
    Complex operator*(Complex a,Complex b){return Complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
    Complex operator/(Complex a,int b){return Complex(a.x/b,a.y/b);}
    void FFT(Complex *E,int f){
        for(int i=0;i<n;i++)if(i<R[i])swap(E[i],E[R[i]]);
        for(int l=1;l<n;l<<=1){
            Complex wn=Complex(cos(pi/l),f*sin(pi/l));
            for(int j=0;j<n;j+=(l<<1)){
                Complex w=Complex(1,0);
                for(int k=0;k<l;k++,w=w*wn){
                    Complex x=E[j+k],y=w*E[j+k+l];
                    E[j+k]=x+y,E[j+k+l]=x-y;
                }
            }
        }
        if(!~f)for(int i=0;i<n;i++)E[i]=E[i]/n;
    }
    char a[N],b[N];
    int main(){
        scanf("%d%d%s%s",&mm,&nn,a,b);
        for(n=1;n<=mm+nn;n<<=1)L++;
        for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
        reverse(a,a+mm);
        for(int i=0;i<mm;i++)if(a[i]=='*')a[i]=0;else a[i]=a[i]-'a'+1;
        for(int i=0;i<nn;i++)if(b[i]=='*')b[i]=0;else b[i]=b[i]-'a'+1;
        for(int i=0;i<mm;i++)A[i].x=a[i];
        for(int i=0;i<nn;i++)B[i].x=b[i]*b[i]*b[i];
        FFT(A,1),FFT(B,1);
        for(int i=0;i<n;i++)ans[i]=A[i]*B[i];
        for(int i=0;i<n;i++)A[i].x=A[i].y=B[i].x=B[i].y=0;
        for(int i=0;i<mm;i++)A[i].x=a[i]*a[i]*a[i];
        for(int i=0;i<nn;i++)B[i].x=b[i];
        FFT(A,1),FFT(B,1);
        for(int i=0;i<n;i++)ans[i]=ans[i]+A[i]*B[i];
        for(int i=0;i<n;i++)A[i].x=A[i].y=B[i].x=B[i].y=0;
        for(int i=0;i<mm;i++)A[i].x=a[i]*a[i];
        for(int i=0;i<nn;i++)B[i].x=b[i]*b[i];
        FFT(A,1),FFT(B,1);
        for(int i=0;i<n;i++)ans[i]=ans[i]-A[i]*B[i]-A[i]*B[i];
        FFT(ans,-1);
        for(int i=mm-1;i<nn;i++)if(fabs(ans[i].x)<1)all++;
        printf("%d
    ",all);
        for(int i=mm-1;i<nn;i++)if(fabs(ans[i].x)<1)printf("%d ",i-mm+2);
    }
  • 相关阅读:
    Safari书签同步
    光标从编辑器移入本页面中的其它输入域后,IE中每次只在编辑器首部插入内容
    JavaScript里模拟sleep
    外观/门面模式(Facade)
    JavaScript中delete操作符不能删除的对象
    Perl与JS的比较(子程序)
    读jQuery之二十一(队列queue)
    JavaScript中“基本类型”之争
    读jQuery之十九(多用途回调函数列表对象)
    工厂模式(Factory)
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532747.html
Copyright © 2020-2023  润新知