【BZOJ3527】【ZJOI2014】—力(FFT)

传送门

这题简单到我这种菜鸡都能A

把两个式子分开考虑

前一半就是
ansi=j=1i1qj(ij)2ans_i=\sum_{j=1}^{i-1}\frac{q_j}{(i-j)^2}
f[i]=1i2f[i]=\frac 1{i^2}
ansi=j=1i1qjfijans_i=\sum_{j=1}^{i-1}q_jf_{i-j}
发现这是一个卷积的形式,直接上fftfft就是了

后一半把qq反过来就一样了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define double long double
inline int read(){
	char ch=getchar();
	int res=0,f=1;
	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
	return res*f;
}
const int N=100005;
const double pi=acos(-1);
double ans0[N],ans1[N],q[N];
struct plx{
	double x,y;
	plx(double _x=0,double _y=0):x(_x),y(_y){}
	friend inline plx operator +(const plx &a,const plx &b){
		return plx(a.x+b.x,a.y+b.y);
	}
	friend inline plx operator -(const plx &a,const plx &b){
		return plx(a.x-b.x,a.y-b.y);
	}
	friend inline plx operator *(const plx &a,const plx &b){
		return plx(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
	}
}a[N<<2],b[N<<2];
int rev[N<<2],lim=1,tim=0;
inline void fft(plx f[],int kd){
	for(int i=0;i<lim;i++)if(i<rev[i])swap(f[i],f[rev[i]]);
	for(int mid=1;mid<lim;mid<<=1){
		plx now=plx(cos(pi/mid),kd*sin(pi/mid));
		for(int i=0;i<lim;i+=(mid<<1)){
			plx w=plx(1,0);
			for(int j=0;j<mid;j++,w=w*now){
				plx a0=f[i+j],a1=w*f[i+j+mid];
				f[i+j]=a0+a1,f[i+j+mid]=a0-a1;
			}	
		}
	}
	if(kd==-1)for(int i=0;i<lim;i++)f[i].x/=1.0*lim;
}
int n;
int main(){
	n=read();
	for(int i=1;i<=n;i++)scanf("%Lf",&q[i]);
	a[0].x=0,a[0].y=0;
	while(lim<=n*2)lim<<=1,tim++;
	for(int i=1;i<=n;i++)a[i].x=q[i];
	for(int i=0;i<lim;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(tim-1));
	for(int i=1;i<=n;i++)b[i].x=1/(1.0*i)/(1.0*i);
	fft(a,1),fft(b,1);
	for(int i=0;i<lim;i++)a[i]=a[i]*b[i];
	fft(a,-1);
	for(int i=1;i<=n;i++)ans0[i]=a[i].x;
	for(int i=0;i<lim;i++)a[i].x=b[i].x=a[i].y=b[i].y=0;
	for(int i=1;i<=n;i++)a[i].x=q[n-i+1];
	for(int i=1;i<=n;i++)b[i].x=1/(1.0*i)/(1.0*i);
	fft(a,1),fft(b,1);
	for(int i=0;i<lim;i++)a[i]=a[i]*b[i];
	fft(a,-1);
	for(int i=1;i<=n;i++)ans1[n-i+1]=a[i].x;
	for(int i=1;i<=n;i++)printf("%.6Lf\n",ans0[i]-ans1[i]);
}
posted @ 2019-03-14 15:35  Stargazer_cykoi  阅读(103)  评论(0编辑  收藏  举报