【题解】P3338 [ZJOI2014]力

题目戳我

( ext{Solution:})

所求即为(sum_{i=1}^j frac{q_i}{(i-j)^2}-sum_{i=j}^n frac{q_i}{(i-j)^2})

(f[i]=q_i,g[i]=frac{1}{i^2})

原式(=sum_{i=1}^j f[i]g[j-i]-sum_{i=j}^n f[i]g[i-j] (p.s. g[i] o i>0))

此时减号左边已经是卷积形式。观察右边:

反转(f,)则右边为(sum_{i=j}^n f[n-i]g[i-j] o sum_{i=0}^{n-j}f[n-j-i]g[i])

观察到(n-j)是一个对每个(j)恒定的值,于是这部分式子也可以写成一个卷积。

于是这题解决了。

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
} 
const double Pi=acos(-1.0);
const int MAXN=4e5+10;
int l,r[MAXN],N,lt=1;
struct cp{
	double x,y;
	cp(double xx=0,double yy=0){x=xx,y=yy;} 
}a[MAXN],b[MAXN],c[MAXN];
cp operator+(cp a,cp b){return cp(a.x+b.x,a.y+b.y);}
cp operator-(cp a,cp b){return cp(a.x-b.x,a.y-b.y);}
cp operator*(cp a,cp b){return cp(a.x*b.x-a.y*b.y,a.y*b.x+a.x*b.y);}
void FFT(cp *A,int tp){
	for(int i=0;i<lt;++i)if(i<r[i])swap(A[i],A[r[i]]);
	for(int mid=1;mid<lt;mid<<=1){
		cp Wn(cos(Pi/mid),tp*sin(Pi/mid));
		for(int R=mid<<1,j=0;j<lt;j+=R){
			cp w(1,0);
			for(int k=0;k<mid;++k,w=w*Wn){
				cp x=A[j+k],y=w*A[mid+j+k];
				A[j+k]=x+y;
				A[mid+j+k]=x-y;
			}
		}
	}
	if(tp==-1){
		for(int i=0;i<lt;++i)A[i].x/=lt;
	}
}
int main(){
	N=read();
	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);
	}
	while(lt<=(N<<1))lt<<=1,l++;
	for(int i=0;i<lt;++i)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
	FFT(a,1);FFT(b,1);FFT(c,1);
	for(int i=0;i<lt;++i)a[i]=a[i]*b[i],c[i]=c[i]*b[i];
	FFT(a,-1),FFT(c,-1);
	for(int i=1;i<=N;++i)printf("%.3lf
",a[i].x-c[N-i].x);
	return 0;
}
原文地址:https://www.cnblogs.com/h-lka/p/14225925.html