zoukankan      html  css  js  c++  java
  • 【JZOJ3617】【ZJOI2014】力

    ╰( ̄▽ ̄)╭

    这里写图片描述
    对于100%的数据,n100000;0<qi<1,000,000,000

    (⊙ ▽ ⊙)

    ri=1i2
    Fj=j1i=0qirj1iGj=j1i=0qn1irji1
    显然Ei=FiGni1
    F,G的这样的式子,我称它为卷积式

    当满足

    f[j]=i=0j1a[i]b[j1i]

    这样的形式时,可以利用快速傅里叶变换
    设多项式A的系数分别为a[0],a[1],a[2],...,a[j1]
    多项式B的系数分别为b[0],b[1],b[2],...,b[j1]
    则多项式C(C=AB)的系数就分别为f[0],f[1],f[2],...,f[j1]

    ( ̄~ ̄)

    #include<iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #define ll long long
    using namespace std;
    const char* fin="ex3617.in";
    const char* fout="ex3617.out";
    const int inf=0x7fffffff;
    const int maxn=500007;
    const double pi=acos(-1);
    struct Z{
        double x,y;
        Z(double _x=0,double _y=0){x=_x;y=_y;}
        Z operator +(const Z &a){return Z(x+a.x,y+a.y);}
        Z operator -(const Z &a){return Z(x-a.x,y-a.y);}
        Z operator *(const Z &a){return Z(x*a.x-y*a.y,x*a.y+y*a.x);}
    }a[maxn],b[maxn],c[maxn],d[maxn];
    int n,m,i,j,k,r[maxn];
    void fft(Z *a,int sig){
        int i,j,k;
        for (i=0;i<n;i++) if (r[i]<i) swap(a[r[i]],a[i]);
        for (i=2;i<=n;i<<=1){
            int ha=i/2;
            for (j=0;j<ha;j++){
                Z w(cos(j*pi*sig/ha),sin(j*pi*sig/ha));
                for (k=j;k<n;k+=i){
                    Z u=a[k],v=w*a[k+ha];
                    a[k]=u+v;
                    a[k+ha]=u-v;
                }
            }
        }
    }
    int main(){
        scanf("%d",&n);
        for (i=0;i<n;i++){
            scanf("%lf",&a[i].x);
            c[n-1-i].x=a[i].x;
        }
        for (i=1;i<n;i++) b[i]=1.0/i/i;
        m=n;
        k=0;
        for (n=1;n<m<<1;n<<=1) k++;
        for (i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(k-1));
    
        fft(a,1);
        fft(c,1);
        fft(b,1);
        for (i=0;i<n;i++) a[i]=a[i]*b[i];
        for (i=0;i<n;i++) c[i]=c[i]*b[i];
        fft(a,-1);
        fft(c,-1);
    
        for (i=0;i<m;i++) printf("%lf
    ",a[i].x/n-c[m-i-1].x/n);
        return 0;
    }

    (⊙v⊙)

    1.

    for (i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(k-1));
    

    这是一行很强的代码,可以用于求出:二进制数ik位意义上的倒转r[i]
    具体地,
    采用递推的形式,r[i]可由r[i shr 1]推得。
    实质是ii shr 1二进制中十分相似,区别只在于i多了一位数。

    2.WARNING
    最后的结果一定要/n

  • 相关阅读:
    query.setXXX预编译赋值 (坑爹的)
    JAVA 预编译执行SQL 之setparameterList用法
    ActiveMQ
    JavaScript DOM日记
    Mysql 详解(三)
    Mysq连接使用
    Mysql详解(二)
    Mysql详解(一)
    Spring MVC 批量导入Excel文件
    《走遍中国》珍藏版(三)
  • 原文地址:https://www.cnblogs.com/hiweibolu/p/6714792.html
Copyright © 2011-2022 走看看