题目大意:Fj=∑i<jqiqj(i−j)2−∑i>jqiqj(i−j)2
令Ei=Fi/qi,求出所有的Ei
首先可以把qj消掉,变成Ej=∑i<jqi(i−j)2−∑i>jqi(i−j)2
我们可以想象F(x)=qx,G(x)=1x2
这样前后两项就都可以化成卷积的形式,然后就可以直接FFT了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 400010
using namespace std;
const double pi=acos(-1);
struct E{double s,x;};
E operator-(const E&x,const E&y){return (E){x.s-y.s,x.x-y.x};}
E operator+(const E&x,const E&y){return (E){x.s+y.s,x.x+y.x};}
E operator*(const E&x,const E&y){return (E){x.s*y.s-x.x*y.x,x.s*y.x+x.x*y.s};}
E omg[N];
void FFT(E *A,E *B,int s,int le,int t)
{
if(le==1){B[s]=A[s];return;}
int l=le/2,i;
for(i=0;i<l;i++)
B[s+i]=A[s+2*i],B[s+l+i]=A[s+2*i+1];
FFT(B,A,s,l,t*2);
FFT(B,A,s+l,l,t*2);
for(i=0;i<l;i++)
{
B[s+i]=A[s+i]+omg[i*t]*A[s+i+l];
B[s+l+i]=A[s+i]-omg[i*t]*A[s+i+l];
}
}
E ffta[N],fftb[N],fftc[N];
void AFFT(double *A,double *B,double *C,int n)
{
int i=1;
while(i<n) i*=2;
n=2*i;
for(i=0;i<=n;i++)
{
ffta[i]=(E){A[i],0};
fftb[i]=(E){B[i],0};
omg[i]=(E){cos(pi*2*i/n),sin(pi*2*i/n)};
}
FFT(ffta,fftc,0,n,1);
FFT(fftb,ffta,0,n,1);
for(i=0;i<n;i++)
fftb[i]=ffta[i]*fftc[i];
for(i=0;i<=n;i++)
omg[i]=(E){cos(-pi*2*i/n),sin(-pi*2*i/n)};
FFT(fftb,fftc,0,n,1);
for(i=0;i<n;i++)
C[i]=fftc[i].s/n;
}
double q[N],s1[N],s2[N],g[N];
int main()
{
int n;
scanf("%d",&n);
int i,j;
for(i=0;i<n;i++)
scanf("%lf",&q[i]);
for(i=1;i<n;i++)
g[i]=1.0/i/i;
AFFT(q,g,s1,n);
for(i=0;i<n/2;i++)
swap(q[i],q[n-1-i]);
AFFT(q,g,s2,n);
for(i=0;i<n;i++)
printf("%.8lf\n",s1[i]-s2[n-1-i]);
}