[ZJOI2014] 力

版权声明:本文为博主原创文章,想转载就转吧! https://blog.csdn.net/qq_35914587/article/details/79949387

题目描述:

定义
fi=i<jqiqj(ij)2i>jqiqj(ij)2
Ei=fi/qi

题目分析:

生成函数第一题~
Ei=i<jqj(ij)2i>jqj(ij)2

gi=(i2)
那么
Ei=i<jqjgiji>jqjgji
第一项很明显就是个卷积了,随便做,主要是后面那项如何搞呢?
pi=qni+1
Ei=i<jqjgiji<jpjgij
那么后面也是个卷积了…
随便搞就行了

题目链接:

BZOJ 3527
Luogu 3338

Ac 代码:

// luogu-judger-enable-o2
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cstring>
const double PI=acos(-1);
const int maxm=410000;
struct complex{
    double real,imag;
    complex(){};
    complex(double _real,double _imag):real(_real),imag(_imag){}
};
inline complex operator + (complex x,complex y){return (complex){x.real+y.real,x.imag+y.imag};}
inline complex operator - (complex x,complex y){return (complex){x.real-y.real,x.imag-y.imag};}
inline complex operator * (complex x,complex y){return (complex){x.real*y.real-x.imag*y.imag,x.real*y.imag+y.real*x.imag};}
int rev[maxm];
complex A1[maxm],A2[maxm],g[maxm];
double q1[maxm],q2[maxm];
inline void FFT(complex *a,int n,int f)
{
    for(int i=0;i<n;i++) if(i<rev[i]) std::swap(a[i],a[rev[i]]);
    for(int i=1;i<n;i<<=1)
    {
        complex wn=(complex){std::cos(PI/i),f*std::sin(PI/i)};
        for(int j=0;j<n;j+=(i<<1))
        {
            complex w=(complex){1,0};
            for(int k=0;k<i;k++,w=w*wn)
            {
                complex x=a[j+k];
                complex y=a[i+j+k]*w;
                a[j+k]=x+y;
                a[i+j+k]=x-y;
            }
        }
    }
    if(f==1) return;
    for(int i=0;i<n;i++) a[i].real=a[i].real/(double)n;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
     scanf("%lf",&q1[i]),q2[n-i-1]=q1[i];
    int len=0,s;
    for(s=1;s<=2*n;s<<=1) len++;
    //printf("%d\n",s);
    for(int i=0;i<s;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
    for(int i=0;i<n;i++) A1[i]=(complex){q1[i],0},A2[i]=(complex){q2[i],0};
    g[0]=(complex){0,0};
    for(int i=1;i<n;i++) g[i]=(complex){(double)1.0/i/i,0};
    FFT(A1,s,1),FFT(A2,s,1),FFT(g,s,1);
    for(int i=0;i<s;i++) A1[i]=A1[i]*g[i],A2[i]=A2[i]*g[i];
    FFT(A1,s,-1),FFT(A2,s,-1);
    for(int i=0;i<n;i++) printf("%.3lf\n",A1[i].real-A2[n-i-1].real);
    return 0;
}
阅读更多

没有更多推荐了,返回首页