• BZOJ 3527 [Zjoi2014]力(FFT)


    题意:中文题

    思路:我们对于这个公式拆成利两部分看,一部分是i<j,一部分是剩下的,我们在i<j的部分可以直接进行化简成卷积的形式,而对于大于的部分比较麻烦,相当于对所有的都替换成n-j,这样你两部分加起来的和还是定值,然后在做一次卷积即可

    代码:(抄胡小兔爷的--->传送门

     
    #include <bits/stdc++.h>
    using namespace std;
     
    const int N = 1000005;
    const double PI=acos(-1.0);
    struct cp
    {
        double r,i;
        cp(){}
        cp(double _r,double _i)
        {
            r=_r;i=_i;
        }
        cp operator +(const cp a)const
        {
            return cp(a.r+r,a.i+i);
        }
        cp operator -(const cp a)const
        {
            return cp(r-a.r,i-a.i);
        }
        cp operator *(const cp a)const
        {
            return cp(r*a.r-i*a.i,r*a.i+i*a.r);
        }
        cp conj()
        {
            return cp(r,-i);
        }
    };
     
    int n=1,m;
    double q[N],res[N];
    cp f[N],f1[N],g[N],omg[N],inv[N];
    void FFT_init(){
        for(int i=0;i<n;i++){
            omg[i]=cp(cos(2*PI*i/n),sin(2*PI*i/n));
            inv[i]=omg[i].conj();
        }
    }
    void fft(cp *a,cp *omg){
        int lim=0;
        while((1 << lim) < n) lim++;
        for(int i=0;i<n;i++){
            int t=0;
            for(int j=0;j<lim;j++)
                if(i >> j&1) t |= 1 << (lim - j - 1);
            if(i<t) swap(a[i],a[t]);
        }
        for(int l=2;l<=n;l*=2){
            int m=l/2;
            for(cp *p=a;p!=a+n;p+=l){
                for(int i=0;i<m;i++){
                    cp t=omg[n/l*i]*p[m+i];
                    p[m+i]=p[i]-t;
                    p[i]=p[i]+t;
                }
            }
        }
    }
     
    int main(){
        scanf("%d",&m);
        for(int i=0;i<m;i++){
            scanf("%lf",&q[i]);
            f[i].r=q[i];
            f1[m - 1 - i].r=q[i];
            if(i) g[i].r=(1.0 / i / i);
        }
        while(n<2*m)n*=2;
        FFT_init();
        fft(f,omg), fft(f1,omg), fft(g,omg);
        for(int i=0;i<n;i++) f[i]=f[i]*g[i],f1[i]=f1[i]*g[i];
        fft(f,inv), fft(f1,inv);
        for(int i=0;i<m;i++){
            res[i] = f[i].r/n - f1[m-1-i].r/n;
        }
        for(int i = 0; i < m; i++){
            printf("%lf
    ", res[i]);
        }
        return 0;
    }
  • 相关阅读:
    mysql InnoDB 索引小记
    Linux shell 脚本小记
    Java中Integer的源码学习
    nginx小记
    位运算小结
    Redis小结
    CSS中nth-child和nth-of-type的简单使用
    Linux awk小记
    mysql小记--基础知识
    让44.1版本的sketch打开更高版本的sketch文件
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/9416229.html
Copyright © 2020-2023  润新知