[ZJOI2014]力
题目描述
输入输出格式
输入格式:
第一行一个整数n。
接下来n行每行输入一个数,第i行表示qi。
输出格式:
n行,第i行输出Ei。
与标准答案误差不超过1e-2即可。
输入输出样例
输入样例#1:
5 4006373.885184 15375036.435759 1717456.469144 8514941.004912 1410681.345880
输出样例#1:
-16838672.693 3439.793 7509018.566 4595686.886 10903040.872
说明
对于30%的数据,n≤1000。
对于50%的数据,n≤60000。
对于100%的数据,n≤100000,0<qi<1000000000。
题解:
E[i]=∑q[j]/(i-j)^2-∑q[j]/(j-i)^2
令g[i]=1/(i^2)
E[i]=∑q[j]*g[i-j]-∑q[j]*g[j-i]
∑q[j]*g[i-j]是卷积形式,求出x^i的系数就行
∑q[j]*g[j-i] (i<j<=n)
=∑q[j+i]*g[j] (i<j+i<=n)=>(0<j<=n-i)
翻转q得到p[n-i]=q[i],t=n-i
=∑q[j+i]*g[j]=∑p[n-i-j]*g[j]=∑q[t-j]*g[j] (0<j<=t)
∑q[t-j]*g[j] (0<j<=t)是卷积形式,求出x^(n-i)的系数就行
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<complex> 7 using namespace std; 8 typedef complex<double> dob; 9 const int N=100000; 10 double pi=acos(-1.0); 11 dob A[8*N],B[8*N],C1[8*N],C2[8*N],G[8*N]; 12 int n,m,len,R[8*N],lg; 13 double q[N+5],ans[2*N]; 14 void FFT(dob *D,double o) 15 {int i,j,k; 16 for (i=0;i<len;i++) 17 if (i<R[i]) swap(D[i],D[R[i]]); 18 for (i=1;i<len;i<<=1) 19 { 20 dob wn(cos(pi/i),sin(o*pi/i)),x,y; 21 for (j=0;j<len;j+=(i<<1)) 22 { 23 dob w(1.0,0); 24 for (k=0;k<i;k++,w*=wn) 25 { 26 x=D[j+k];y=w*D[i+j+k]; 27 D[j+k]=x+y; 28 D[i+j+k]=x-y; 29 } 30 } 31 } 32 } 33 int main() 34 {int i; 35 cin>>n; 36 for (i=1;i<=n;i++) 37 G[i]=1.0/(double)i/(double)i; 38 for (i=1;i<=n;i++) 39 { 40 scanf("%lf",&q[i]); 41 A[i]=q[i]; 42 } 43 for (i=1;i<=n;i++) 44 B[i]=q[n-i+1]; 45 len=1; 46 while (len<=2*n+2) len*=2,lg++; 47 for (i=0;i<=len;i++) 48 R[i]=(R[i>>1]>>1)|((i&1)<<(lg-1)); 49 FFT(A,1);FFT(B,1);FFT(G,1); 50 for (i=0;i<len;i++) 51 C1[i]=A[i]*G[i],C2[i]=B[i]*G[i]; 52 FFT(C1,-1);FFT(C2,-1); 53 for (i=1;i<=n;i++) 54 { 55 ans[i]=C1[i].real()/len-C2[n-i+1].real()/len; 56 } 57 for (i=1;i<=n;i++) 58 printf("%.3lf\n",ans[i]); 59 }