定义
求E[i] = F[i] / q[i]
经过推导发现最后形成了卷积的形式,之后直接套用FFT就行了。
注意卷积卷起来之后占用的是2倍的空间。。
#define _CRT_SECURE_NO_WARNINGS
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1000010
using namespace std;
const double PI = acos(-1.0);
struct Complex{
double x,y;
Complex(double _,double __ = .0):x(_),y(__) {}
Complex() {}
void operator +=(const Complex &a) {
x += a.x,y += a.y;
}
void operator -=(const Complex &a) {
x -= a.x,y -= a.y;
}
void operator /=(double a) {
x /= a,y /= a;
}
void operator *=(const Complex &a) {
double _ = x * a.x - y * a.y,__ = x * a.y + y * a.x;
x = _,y = __;
}
Complex operator +(const Complex &a)const {
return Complex(x + a.x,y + a.y);
}
Complex operator -(const Complex &a)const {
return Complex(x - a.x,y - a.y);
}
Complex operator /(double a)const {
return Complex(x / a,y / a);
}
Complex operator *(const Complex &a)const {
return Complex(x * a.x - y * a.y,x * a.y + y * a.x);
}
};
inline void FFT(Complex A[],int cnt,int flag)
{
for(int i = 0,k = 0; i < cnt; ++i) {
if(i < k) swap(A[i],A[k]);
for(int j = cnt >> 1; (k ^= j) < j; j >>= 1);
}
Complex w,wn,t;
for(int k = 2; k <= cnt; k <<= 1)
for(int i = 0,j; i < cnt; i += k) {
wn = Complex(cos(2 * PI / k),flag * sin(2 * PI / k));
for(w = 1.0,j = 0; j < k >> 1; ++j,w *= wn) {
t = w * A[i + j + (k >> 1)];
A[i + j + (k >> 1)] = A[i + j] - t;
A[i + j] += t;
}
}
if(!~flag)
for(int i = 0; i < cnt; ++i)
A[i] /= cnt;
}
Complex A[MAX],B[MAX];
int cnt;
double src[MAX],ans[MAX];
int main()
{
cin >> cnt;
for(int i = 0; i < cnt; ++i)
scanf("%lf",&src[i]);
int l = 1;
for(; l <= cnt << 1; l <<= 1);
for(int i = 0; i < cnt; ++i) A[i] = Complex(src[i]);
for(int i = 1; i < cnt; ++i) B[i] = Complex(1.0 / i / i);
FFT(A,l,1),FFT(B,l,1);
for(int i = 0; i < l; ++i)
A[i] *= B[i];
FFT(A,l,-1);
for(int i = 0; i < cnt; ++i)
ans[i] = A[i].x;
reverse(src,src + cnt);
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
for(int i = 0; i < cnt; ++i) A[i] = Complex(src[i]);
for(int i = 1; i < cnt; ++i) B[i] = Complex(1.0 / i / i);
FFT(A,l,1),FFT(B,l,1);
for(int i = 0; i < l; ++i)
A[i] *= B[i];
FFT(A,l,-1);
for(int i = 0; i < cnt; ++i)
ans[i] -= A[cnt - i - 1].x;
for(int i = 0; i < cnt; ++i)
printf("%lf\n",ans[i]);
return 0;
}
原文地址:http://blog.csdn.net/jiangyuze831/article/details/44055331