• 【BZOJ】2194: 快速傅立叶之二


    【题意】请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5。 a,b中的元素均为小于等于100的非负整数。

    【算法】快速傅里叶变换(FFT)处理卷积

    【题解】题目要求:

    $$C_k=sum_{i=k}^{n-1}A_i*B_{i-k}$$

    令B'为B的数组反转,转化成和为定值的形式,即:

    $$C_k=sum_{i=k}^{n-1}A_i*B'_{n+k-1-i}$$

    因为:

    $$A_i=0,iin[n,n+k-1]$$

    $$B_{n+k-1-i}=0,iin[0,k-1]$$

    所以可以扩展式子的上下界,即:

    $$C_k=D_{n+k-1}=sum_{i=0}^{n+k-1}A_i*B'_{n+k-1-i}$$

    这就可以用FFT处理卷积了。

    复杂度O(n log n)。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=300010;
    const double PI=acos(-1);
    int n;
    struct cp{
        double x,y;
        cp(double a,double b){x=a;y=b;}
        cp(){x=y=0;}
        cp operator + (cp a){return (cp){x+a.x,y+a.y};}
        cp operator - (cp a){return (cp){x-a.x,y-a.y};}
        cp operator * (cp a){return (cp){x*a.x-y*a.y,x*a.y+y*a.x};}
    }a[maxn],b[maxn];
    void fft(cp *a,int n,int f){
        int k=0;
        for(int i=0;i<n;i++){
            if(i>k)swap(a[i],a[k]);
            for(int j=n>>1;(k^=j)<j;j>>=1);
        }
        for(int l=2;l<=n;l<<=1){
            int m=l>>1;
            cp wn=(cp){cos(2*PI*f/l),sin(2*PI*f/l)};
            for(cp *p=a;p!=a+n;p+=l){
                cp w=(cp){1,0};
                for(int i=0;i<m;i++){
                    cp t=p[i+m]*w;
                    p[i+m]=p[i]-t;
                    p[i]=p[i]+t;
                    w=w*wn;
                }
            }
        }
        if(f==-1){for(int i=0;i<n;i++)a[i].x/=n;}
    }
    int main(){
        scanf("%d",&n);
        for(int i=0;i<n;i++)scanf("%lf %lf",&a[i].x,&b[n-i-1].x);
        int N=1;while(N<n*2)N*=2;
        fft(a,N,1);fft(b,N,1);
        for(int i=0;i<N;i++)a[i]=a[i]*b[i];//2n
        fft(a,N,-1);
        for(int i=n-1;i<2*n-1;i++)printf("%d
    ",(int)(a[i].x+0.1));
        return 0;
    }
    View Code

    只要和为定值的形式就可以卷积,如果看着很奇怪就将其中一个数组下标变成i,然后扩展上下界。

  • 相关阅读:
    Python 脚本如何执行另一个脚本
    Yarn集群的搭建、Yarn的架构和WordCount程序在集群提交方式
    Mapreduce概述和WordCount程序
    HDFS及其各组件的机制
    HDFS常用API(2)
    HDFS常用API(1)
    HDFS分布式文件系统的常用命令行操作
    大数据及Hadoop的概述
    谷歌浏览器加载速度慢的解决办法!!!
    Idea中lombok不生效原因
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8418113.html
Copyright © 2020-2023  润新知