P3338 力
题目描述
题解
E
i
=
f
i
q
i
=
∑
j
=
1
i
−
1
q
j
(
i
−
j
)
2
−
∑
j
=
i
+
1
n
q
j
(
i
−
j
)
2
E_i=\frac{f_i}{q_i}=\sum\limits_{j=1}^{i-1}\frac{q_j}{(i-j)^2}-\sum\limits_{j=i+1}^{n}\frac{q_j}{(i-j)^2}
Ei=qifi=j=1∑i−1(i−j)2qj−j=i+1∑n(i−j)2qj
由于
j
=
0
,
i
=
j
j=0,i=j
j=0,i=j不会影响答案
E
i
=
∑
j
=
0
i
q
j
(
i
−
j
)
2
−
∑
j
=
i
n
q
j
(
i
−
j
)
2
E_i=\sum\limits_{j=0}^{i}\frac{q_j}{(i-j)^2}-\sum\limits_{j=i}^{n}\frac{q_j}{(i-j)^2}
Ei=j=0∑i(i−j)2qj−j=i∑n(i−j)2qj
令
f
[
i
]
=
q
i
,
g
[
i
]
=
1
i
2
f[i]=q_i,g[i]=\frac{1}{i^2}
f[i]=qi,g[i]=i21
则有
E
i
=
∑
j
=
0
i
f
[
j
]
g
[
i
−
j
]
−
∑
j
=
i
n
f
[
j
]
g
[
j
−
i
]
E_i=\sum\limits_{j=0}^if[j]g[i-j]-\sum\limits_{j=i}^nf[j]g[j-i]
Ei=j=0∑if[j]g[i−j]−j=i∑nf[j]g[j−i]
于是前半部分已经化成了卷积的形式,考虑继续转化后半部分
E
i
=
∑
j
=
0
i
f
[
j
]
g
[
i
−
j
]
−
∑
j
=
0
n
−
i
f
[
j
+
i
]
g
[
j
]
E_i=\sum\limits_{j=0}^if[j]g[i-j]-\sum\limits_{j=0}^{n-i}f[j+i]g[j]
Ei=j=0∑if[j]g[i−j]−j=0∑n−if[j+i]g[j]
这里用到了翻转的套路。
令
f
′
[
i
]
=
f
[
n
−
i
]
f'[i]=f[n-i]
f′[i]=f[n−i]
E
i
=
∑
j
=
0
i
f
[
j
]
g
[
i
−
j
]
−
∑
j
=
0
n
−
i
f
′
[
n
−
j
−
i
]
g
[
j
]
E_i=\sum\limits_{j=0}^if[j]g[i-j]-\sum\limits_{j=0}^{n-i}f'[n-j-i]g[j]
Ei=j=0∑if[j]g[i−j]−j=0∑n−if′[n−j−i]g[j]
于是后半部分也转化成了卷积,可以愉快地套FFT板子了
代码
#include <cmath>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int M=4e5+9;
const double pi=acos(-1.0);
int n,m,r[M],l,lim=1,aa,bb;
struct complex{
double x,y;
complex(double xx=0,double yy=0){x=xx,y=yy;}
friend inline complex operator+(complex a,complex b){return complex(a.x+b.x,a.y+b.y);}
friend inline complex operator-(complex a,complex b){return complex(a.x-b.x,a.y-b.y);}
friend inline complex operator*(complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
friend inline complex operator/(complex a,double b){return complex(a.x/b,a.y/b);}
friend inline complex operator*(complex a,double b){return complex(a.x*b,a.y*b);}
}a[M],b[M],c[M];
void FFT(complex *A,int type){
for(int i=0;i<lim;i++) if(i<r[i]) swap(A[i],A[r[i]]);
for(int mid=1;mid<lim;mid<<=1){
complex W(cos(pi/mid),type*sin(pi/mid));
for(int R=mid<<1,j=0;j<lim;j+=R){
complex w(1,0);
for(int k=0;k<mid;k++,w=w*W){
complex x=A[j+k],y=w*A[j+k+mid];
A[j+k]=x+y;
A[j+mid+k]=x-y;
}
}
}if(type==-1) for(int i=0;i<lim;i++) A[i]=A[i]/lim;
}
signed main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lf",&a[i].x);
c[n-i].x=a[i].x;
b[i].x=(double)(1.0/i/i);
}while(lim<=n+n) lim<<=1,l++;
for(int i=0;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
FFT(a,1),FFT(b,1),FFT(c,1);
for(int i=0;i<lim;i++) a[i]=a[i]*b[i],c[i]=c[i]*b[i];
FFT(a,-1),FFT(c,-1);
for(int i=1;i<=n;i++) printf("%.3lf\n",a[i].x-c[n-i].x);
return 0;
}