link

推柿子。

\(f(i)=\frac{1}{i^2},g(i)=q_i\) 。特别地,认为 \(f(0)=0\)

\[E_j=\sum\limits_{i=0}^{j-1}\frac{q_i}{(i-j)^2}-\sum\limits_{i=j+1}^n\frac{q_i}{(i-j)^2}=\sum\limits_{i=0}^jf(j-i)g(i)-\sum\limits_{i=j+1}^nf(i-j)g(i) \]

前面可以直接卷积。看一下后面。令 \(t(i)=g(n-i)\)

\[\sum\limits_{i=j+1}^nf(i-j)g(i)=\sum\limits_{i=0}^{n-j}f(i)g(i+j)=\sum\limits_{i=0}^{n-j}f(i)t(n-i-j) \]

于是后面的也可以卷了。

另外通过这道题可以归纳出卷积的一般形式,即 \(\sum\limits_{i=0}^nA_iB_{n-i}\) 的值是A和B的卷积的第n项。这个式子最大的特点是A和B下标之和为定值,而且 \([0,i]\) 都被作为A的下标恰好一次。

code。非递归版会比递归版快三到四成。

#include<bits/stdc++.h>
//#define zczc
const int N=100010*4;
const double Pi=acos(-1.0);
using namespace std;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}

struct node{double a,b;}f[N],g[N],t[N];
node operator +(node s1,node s2){return (node){s1.a+s2.a,s1.b+s2.b};}
node operator -(node s1,node s2){return (node){s1.a-s2.a,s1.b-s2.b};}
node operator *(node s1,node s2){return (node){s1.a*s2.a-s1.b*s2.b,s1.a*s2.b+s1.b*s2.a};}

int m,cnt[N];

node s[N];
void FFT(node a[],int limit,int type){
	for(int i=0;i<limit;i++)s[i]=a[cnt[i]];
	for(int len=1;len<limit;len<<=1){
		int sl=len*2;
		node ww=(node){cos(2*Pi/sl),type*sin(2*Pi/sl)};
		for(int l=0;l+sl<=limit;l+=sl){
			node w=(node){1,0};
			for(int i=0;i<len;i++,w=w*ww){
				node a1=s[l+i],a2=s[l+len+i]*w;
				s[l+i]=a1+a2,s[l+len+i]=a1-a2;
			}
		}
	}
	for(int i=0;i<limit;i++)a[i]=s[i];
}

signed main(){
	
	#ifdef zczc
	freopen("in.txt","r",stdin);
	#endif
	
	read(m);
	for(int i=1;i<=m;i++){
		scanf("%lf",&g[i].a);
		t[m-i]=g[i];
		f[i].a=(double)1/i/i;
	}
	int limit=1;while(limit<=m*2)limit<<=1;
	int scnt=0;while((1<<scnt)!=limit)scnt++;
	for(int i=1;i<=limit;i++)cnt[i]=(cnt[i>>1]>>1)+((i&1)<<scnt-1);
	FFT(f,limit,1);FFT(g,limit,1);FFT(t,limit,1);
	for(int i=0;i<limit;i++)g[i]=g[i]*f[i],t[i]=t[i]*f[i];
	FFT(g,limit,-1);FFT(t,limit,-1);
	for(int i=0;i<limit;i++)g[i].a/=limit,t[i].a/=limit;
	for(int i=1;i<=m;i++)printf("%.3f\n",g[i].a-t[m-i].a);
	
	return 0;
}
posted @ 2022-06-29 16:10  Feyn618  阅读(60)  评论(0编辑  收藏  举报