zoukankan      html  css  js  c++  java
  • 【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,然后扩展上下界。

  • 相关阅读:
    IHttpHandler做文件防盗链接
    使用SQL的全文搜索功能构建 Web 搜索应用程序
    Google 二维条码 API
    Flash Media Server 入门教程
    Janus WinForms Controls Suite v2.0.1000
    如何将数据大容量加载到合并发布中的表(复制 TransactSQL 编程)
    转:CentOS 5.4下的Memcache安装
    转:用php读取xml数据
    HPUX启动和关闭
    目录,文件操作详谈—php
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8418113.html
Copyright © 2011-2022 走看看