BZOJ 3527: [Zjoi2014]力

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3527

设f[i]=q[i],g[i]=1/(i^2)

E[i]=∑f[j]*g[i-j](1≤j≤i)-∑f[j]*g[i-j](i+1≤j≤n)

左边做卷积,右边就令t=n-i,f'[i]=f[n-i],右边就变成∑f'[j]-g[t-j](0≤j≤t)

设a[i]=f[i]*g[i],b[i]=f'[i]*g[i]

那么ans[i]=a[i]*b[n-i]

#include<cstring>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<complex>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define maxn 350050
#define mm 1000000007
#define pi acos(-1)
#define ll long long
using namespace std;
typedef complex<double> E;
E a[maxn],b[maxn],f[maxn],_f[maxn],g[maxn];
double x;
int n,m,L,rev[maxn];
ll read(){
    ll x=0,f=1; char ch=getchar();
    while (!isdigit(ch)){if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)){x=x*10+ch-'0'; ch=getchar();}
    return x*f; 
}
void fft(E *a,int f){
    rep(i,0,n-1) if (i>rev[i]) swap(a[i],a[rev[i]]);
    for (int i=1;i<n;i<<=1){
        E wn(cos(pi/i),f*sin(pi/i));
        for (int j=0,p=i<<1;j<n;j+=p){
            E w(1,0);
            for (int k=0;k<i;k++,w=w*wn){
                E x=a[j+k],y=w*a[j+k+i];
                a[j+k]=x+y,a[j+k+i]=x-y;
            }
        }
    }
    if (f==-1) rep(i,0,n-1) a[i]/=n;  
}
int main(){
    n=read();
    rep(i,1,n) {
        scanf("%lf",&x);
        f[i]=x; _f[n-i]=x;
    } 
    rep(i,1,n) g[i]=1.0/i/i;
    m=n*2; for (n=1;n<=m;n<<=1) L++;
    rep(i,0,n) rev[i]=rev[i>>1]>>1|((i&1)<<(L-1));
    fft(f,1); fft(_f,1); fft(g,1);
    rep(i,0,n-1) a[i]=f[i]*g[i];
    rep(i,0,n-1) b[i]=_f[i]*g[i];
    fft(a,-1); fft(b,-1);
    rep(i,1,m/2) printf("%.3lf\n",a[i].real()-b[m/2-i].real());
    return 0;
}

 

posted on 2016-01-04 21:57  ctlchild  阅读(187)  评论(0编辑  收藏  举报

导航