【FFT】[ZJOI2014]力

题目

【FFT】[ZJOI2014]力_第1张图片

思路

【FFT】[ZJOI2014]力_第2张图片

代码

#include
using namespace std; 
const int N=4e5+77;
const double pi=3.141592653589;
int r[N],n; 
struct yjy
{
     
	double x,y;
	yjy(double a=0,double b=0):x(a),y(b){
     }
	yjy operator +(yjy a){
     return yjy(x+a.x,y+a.y);}
	yjy operator -(yjy a){
     return yjy(x-a.x,y-a.y);}
	yjy operator *(yjy a){
     return yjy(x*a.x-y*a.y,x*a.y+y*a.x);}
}a[N],b[N],c[N],w[N];
void dft(yjy *a,int n,int f)
{
     
	for(int i=0; i<n; i++) if(i<r[i]) swap(a[i],a[r[i]]);
	for(int i=2; i<=n; i<<=1)
	{
     
		int now=i>>1;
		yjy wn=w[i]; wn.y*=f;
		for(int j=0; j<n; j+=i)
		{
     
			yjy w=yjy(1,0),x,y;
			for(int k=j; k<j+now; k++,w=w*wn)
			{
     
				x=a[k],y=w*a[k+now];
				a[k]=x+y; a[k+now]=x-y;
			}
		}
	}
	if(f==-1) for(int i=0; i<n; i++) a[i].x/=n;
}
int 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);
	}
	int lim=1,L=0; while(lim<=(n<<1)) lim<<=1,++L;
	for(int i=0; i<lim; i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1));
	for(int i=2; i<=lim; i<<=1) w[i]=yjy(cos(2*pi/i),sin(2*pi/i));
	dft(a,lim,1),dft(b,lim,1),dft(c,lim,1);
	for(int i=0; i<lim; i++) a[i]=a[i]*b[i],c[i]=c[i]*b[i];
	dft(a,lim,-1),dft(c,lim,-1);
	for(int i=1; i<=n; i++) printf("%.3lf\n",a[i].x-c[n-i].x);
}

你可能感兴趣的:(【FFT】[ZJOI2014]力)