力「ZJOI2014」
题意
给出数列\(q\)以及\(F_j\)的定义:
\(F_j=\sum_{i<j} \frac{q_iq_j}{(i-j)^2}-\sum_{j<i} \frac{q_iq_j}{(i-j)^2}\)
令\(E_i=\frac{F_i}{q_i}\),求\(E_i\)。
思路
准确的说我们要求\(E_j\),
带入式子得到\(E_j=\sum{i<j}\frac{q_i}{(i-j)^2}-\sum_{j<i}\frac{q_i}{(i-j)^2}\)
那么就是\(E_j=\sum^{j-1}_{i=1}\frac{q_i}{(i-j)^2}-\sum^n_{i=j+1}\frac{q_i}{(i-j)^2}\)
设\(f(i)=q_i, g(i)=\frac{1}{i^2}\)
带入得到\(E_j=\sum^{j-1}_{i=1}f(i)g(j-i)-\sum^n_{i=j+1}f(i)g(j-i)=\sum^{j-1}_{i=1}f(i)g(j-i)-sum^{n-j}_{i=1}f(i-j)g(-i)\)
前者卷积,后者翻转之后卷积。
代码
#include <bits/stdc++.h>
using namespace std;
namespace StandardIO {
template<typename T> inline void read (T &x) {
x=0;T f=1;char c=getchar();
for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
x*=f;
}
template<typename T> inline void write (T x) {
if (x<0) putchar('-'),x=-x;
if (x>=10) write(x/10);
putchar(x%10+'0');
}
}
using namespace StandardIO;
namespace Solve {
const int N=600000;
const double pi=acos(-1);
typedef complex<double> cx;
int n,m,L;
cx a[N],b[N];
int R[N];
double x;
inline void fft (cx *tmp,int type) {
for (register int i=0; i<n; ++i) if (i<R[i]) swap(tmp[i],tmp[R[i]]);
for (register int i=1; i<n; i<<=1) {
cx wn(cos(pi/i),type*sin(pi/i));
for (register int j=0; j<n; j+=(i<<1)) {
cx w(1,0);
for (register int k=0; k<i; ++k,w*=wn) {
cx s=tmp[j+k],t=tmp[j+k+i]*w;
tmp[j+k]=s+t,tmp[j+k+i]=s-t;
}
}
}
}
inline void MAIN () {
read(n);
for (register int i=0; i<n; ++i) scanf("%lf",&x),a[i]=x;
for (register int i=0; i<n; ++i) b[i]=-1.0/(static_cast<double>(n-i)*(n-i));
for (register int i=n+1; i<=2*n; ++i) b[i]=1.0/(static_cast<double>(i-n)*(i-n));
m=2*n;
for (n=1; n<=m; n<<=1) ++L;
for (register int i=0; i<n; ++i) R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
fft(a,1),fft(b,1);
for (register int i=0; i<n; ++i) a[i]*=b[i];
fft(a,-1);
for (register int i=m/2; i<=m-1; ++i) printf("%.3lf\n",a[i].real()/n);
}
}
int main () {
Solve::MAIN();
}