Luogu P3338 [ZJOI2014]力

\(E_i=\sum\limits_{i=1}^{j-1}\frac{q_i}{(i-j)^2}-\sum\limits_{i=j+1}^n \frac{q_i}{(i-j)^2}\) ,设 \(f_i=\frac{1}{i^2}\),那原式前半部分相当于是 \(q\times f\) ,后半部分相当于是 \(rev(q) \times f\)

卷积即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#define R register int
using namespace std;
namespace Luitaryi {
const double PI=acos(-1.0);
const int N=600010;
int n,K,len,p[N];
struct cpl {
  double x,y;
  inline cpl operator + (const cpl& that) const
    {return (cpl){x+that.x,y+that.y};}
  inline cpl operator - (const cpl& that) const 
    {return (cpl){x-that.x,y-that.y};}
  inline cpl operator * (const cpl& that) const 
    {return (cpl){x*that.x-y*that.y,x*that.y+y*that.x};}
}a[N],b[N],f[N];
inline void fft(cpl* a,int op) {
  for(R i=0;i<K;++i) if(i<p[i]) swap(a[i],a[p[i]]);
  for(R l=1;l<K;l<<=1) {
    register cpl w1=(cpl){cos(PI/l),op*sin(PI/l)},wn,x,y;
    for(R len=l<<1,i=0;i<K;i+=len) {
      wn=(cpl){1,0};
      for(R j=0;j<l;++j,wn=wn*w1) 
        x=a[i+j],y=a[i+j+l]*wn,a[i+j]=x+y,a[i+j+l]=x-y;
    }
  }
}
inline void main() {
  scanf("%d",&n);
  for(R i=1;i<=n;++i) scanf("%lf",&a[i].x),b[n-i+1].x=a[i].x;
  for(R i=1;i<=n;++i) f[i].x=1.0/(1.0*i*i);
  K=1; while(K<=n*2) K<<=1,++len;
  for(R i=0;i<K;++i) p[i]=(p[i>>1]>>1)|((i&1)<<(len-1));
  fft(a,1),fft(b,1),fft(f,1);
  for(R i=0;i<K;++i) a[i]=a[i]*f[i],b[i]=b[i]*f[i];
  fft(a,-1),fft(b,-1);
  for(R i=1;i<=n;++i) a[i].x/=K,b[i].x/=K;
  for(R i=1;i<=n;++i) printf("%lf\n",a[i].x-b[n-i+1].x);
}
} signed main() {Luitaryi::main(); return 0;}

2020.01.16

posted @ 2020-01-16 19:15  LuitaryiJack  阅读(114)  评论(0编辑  收藏  举报