• [BZOJ]2194: 快速傅立叶之二


    题目大意:给定序列a,b,求序列c满足c[k]=sigma(a[i]*b[i-k]) (k<=i<n)。(n<=10^5)

    思路:观察发现就是普通的卷积反一反(翻转ab其中一个后做卷积,倒着输出即可),FFT模板复习。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        int x;char c;
        while((c=getchar())<'0'||c>'9');
        for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
        return x;
    }
    #define MN 262144
    struct cp
    {
        double r,i;
        cp(double r=0,double i=0):r(r),i(i){}
        cp operator+(cp b){return cp(r+b.r,i+b.i);}
        cp operator-(cp b){return cp(r-b.r,i-b.i);}
        cp operator*(cp b){return cp(r*b.r-i*b.i,r*b.i+i*b.r);}
    }w[2][MN+5],a[MN+5],b[MN+5],c[MN+5];
    const double pi=acos(-1);
    int N,R[MN+5];
    void init(int n)
    {
        for(N=1;N<n;N<<=1);
        int i,j,k;cp g(cos(2*pi/N),sin(2*pi/N));
        for(i=w[0][0].r=1;i<N;++i)w[0][i]=w[0][i-1]*g;
        for(i=w[1][0].r=1;i<N;++i)w[1][i]=w[0][N-i];
        for(i=j=0;i<N;R[++i]=j)for(k=N>>1;(j^=k)<k;k>>=1);
    }
    void fft(cp*x,int v)
    {
        int i,j,k;
        for(i=j=0;i<N;++i)if(i<R[i])swap(x[i],x[R[i]]);
        for(i=1;i<N;i<<=1)for(j=0;j<N;j+=i<<1)for(k=0;k<i;++k)
        {
            cp p=x[i+j+k]*w[v][N/(i<<1)*k];
            x[i+j+k]=x[j+k]-p;x[j+k]=x[j+k]+p;
        }
        if(v)for(i=0;i<N;++i)x[i].r/=N,x[i].i/=N;
    }
    int main()
    {
        int n=read(),i;
        for(i=0;i<n;++i)a[n-i-1].r=read(),b[i]=read();
        init(n<<1);fft(a,0);fft(b,0);
        for(i=0;i<N;++i)c[i]=a[i]*b[i];fft(c,1);
        for(i=n;i--;)printf("%d
    ",int(c[i].r+0.5));
    }
  • 相关阅读:
    scrollLeft、offsetLeft、clientLeft、clientHeight区分
    表格斜线
    td里的所有STYLE
    对输入框输入的数字进行格式控制,是很实用的效果
    MSComm控件使用详解
    如何用javascripr动态添加table?
    TeeChart的安装 delphi7
    DELPHI 字符串分割处理
    转正则表达式 简单
    求解:js函数在预编译期间的谜 简单
  • 原文地址:https://www.cnblogs.com/ditoly/p/BZOJ2194.html
Copyright © 2020-2023  润新知