[bzoj3527][Zjoi2014]力【FFT】
【题目描述】
Description
给出n个数qi,给出Fj的定义如下:
令Ei=Fi/qi,求Ei.
Input
第一行一个整数n。
接下来n行每行输入一个数,第i行表示qi。
n≤100000,0<qi<1000000000
Output
n行,第i行输出Ei。与标准答案误差不超过1e-2即可。
Sample Input
5
4006373.885184
15375036.435759
1717456.469144
8514941.004912
1410681.345880
4006373.885184
15375036.435759
1717456.469144
8514941.004912
1410681.345880
Sample Output
-16838672.693
3439.793
7509018.566
4595686.886
10903040.872
3439.793
7509018.566
4595686.886
10903040.872
HINT
Source
【题解】
Ei= ∑ qj / (i-j)^2 (i<j) - ∑ qj / (i-j)^2 (i>j)
构造多项式A=q1*x+q2*x^2+...+qn*x^n;
B=-1/(n-1)^2 *x+-1/(n-2)^2 * x^2 +...+ 0 * x^n +... + 1/(n-1)^2 * x^(2n-1)
将A卷上B,第n+i项的系数为第Ei的答案。
/* -------------- user Vanisher problem bzoj-3527 ----------------*/ # include <bits/stdc++.h> # define N 1010000 # define ll long long using namespace std; double pi=acos(-1.0); int read(){ int tmp=0, fh=1; char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();} while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();} return tmp*fh; } struct number{ double x,y; }a[N],b[N]; number operator +(number x, number y){return (number){x.x+y.x,x.y+y.y};} number operator -(number x, number y){return (number){x.x-y.x,x.y-y.y};} number operator *(number x, number y){return (number){x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x};} double sqr(double x){return x*x;} int n; void FFT(number *a, int n, int tag){ for (int i=0,j=0; i<n; i++){ if (i<j) swap(a[i],a[j]); for (int k=n/2; k>0; k>>=1) if ((j&k)!=0) j=j-k; else { j=j+k; break; } } for (int i=2; i<=n; i<<=1){ number w={cos(2*pi/i),sin(2*pi/i*tag)}; for(int j=0; j<n; j+=i){ number wn={1,0}; for (int k=j; k<j+i/2; k++,wn=wn*w){ number x=a[k], y=a[k+i/2]*wn; a[k]=x+y; a[k+i/2]=x-y; } } } if (tag==-1) for (int i=0; i<n; i++) a[i].x=a[i].x/n; } int main(){ n=read(); for (int i=1; i<=n; i++) scanf("%lf",&a[i].x); for (int i=1; i<n; i++){ b[i].x=-1.0/sqr(n-i); b[n+n-i].x=1.0/sqr(n-i); } int nn=1; while (nn<=n*2) nn<<=1; FFT(a,nn,1); FFT(b,nn,1); for (int i=0; i<nn; i++) a[i]=a[i]*b[i]; FFT(a,nn,-1); for (int i=n+1; i<=n+n; i++) printf("%.3lf\n",a[i].x); return 0; }