title
Description
Given \ (n-\) number \ (Q_I \) , gives \ (F_j \) is defined as follows:
\(F_j = \sum_{i<j}\frac{q_i q_j}{(i-j)^2 }-\sum_{i>j}\frac{q_i q_j}{(i-j)^2 }\)
令 \(E_i=\frac{F_i}{q_i}\),求 \(E_i\)
analysis
\[ E_j=\frac{F_j}{q_j}=\sum_{i<j}\frac{q_i}{(i-j)^2}-\sum_{i>j}\frac{q_i}{(i-j)^2} \]
设
\[ f[i]=q_i,g[i]=\frac{1}{i^2} \]
则原式为
\[ \sum_{i<j}f[i]g[j-i]-\sum_{i>j}f[i]g[j-i] \]
即
\[ \sum_{i=0}^{j-1}f[i]g[j-i]-\sum_{i=j+1}^{n}f[i]g[j-i] \]
Set \ (f '\) of \ (F \) value is reversed, the original formula
\ [\ sum_ {i = 0 } ^ {j-1} f [i] g [ji] - \ sum_ { i = 0} ^ {j- 1} f '[i] g [ji] \]
Easy to see that this is a form of convolution directly \ (FFT \) can be.
code
#include<bits/stdc++.h>
typedef long double ld;
const int maxn=5e5+10;
const ld Pi=acos(-1);
namespace IO
{
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
}
using IO::read;
struct Orz{double a,b;}A[maxn],B[maxn],C[maxn],W[maxn];
inline Orz operator + (Orz a,Orz b) { return (Orz){a.a+b.a,a.b+b.b}; }
inline Orz operator - (Orz a,Orz b) { return (Orz){a.a-b.a,a.b-b.b}; }
inline Orz operator * (Orz a,Orz b) { return (Orz){a.a*b.a-a.b*b.b,a.a*b.b+a.b*b.a}; }
int N,r[maxn],l;
inline void FFT(Orz *P,int opt)
{
for (int i=1; i<N; ++i) if (i<r[i]) std::swap(P[i],P[r[i]]);
for (int i=1; i<N; i<<=1)
for (int p=i<<1,j=0; j<N; j+=p)
for (int k=0; k<i; ++k)
{
Orz w=(Orz){W[N/i*k].a,W[N/i*k].b*opt};
Orz x=P[j+k], y=w*P[j+k+i];
P[j+k]=x+y, P[j+k+i]=x-y;
}
if (opt==-1)
for (int i=0; i<N; ++i) P[i].a/=N;
}
int main()
{
int n;read(n);
for (N=1; N<=(n<<1); N<<=1) ++l;
for (int i=0; i<N; ++i) r[i]=( (r[i>>1]>>1) | ((i&1)<<(l-1)) );
for (int i=1; i<N; i<<=1)
for (int k=0; k<i; ++k) W[N/i*k]=(Orz){cos(k*Pi/i),sin(k*Pi/i)};
for (int i=1; i<=n; ++i) scanf("%lf",&A[i].a), B[n+1-i].a=A[i].a;
for (int i=1; i<=n; ++i) C[i].a=(1.0/(ld)i)/(ld)i;
FFT(A,1),FFT(B,1),FFT(C,1);
for (int i=0; i<N; ++i) A[i]=A[i]*C[i], B[i]=B[i]*C[i];
FFT(A,-1),FFT(B,-1);
for (int i=1; i<=n; ++i) printf("%.3lf\n",A[i].a-B[n+1-i].a);
return 0;
}