zjoi 力

显然fft维护卷积就可以了

发现fft里面会改变很多东西 要还原一下

#include <bits/stdc++.h>
#define dob complex<double>
using namespace std;
const int N=3e5;
const double pi=acos(-1.0);
dob a[N],a2[N],b[N];
int r[N],l;
double ans1[N],sum[N];
int n,m;
void fft(dob *a,int o)
{
    for (int i=0;i<n;i++)
      if (i>r[i]) swap(a[i],a[r[i]]);
    for (int i=1;i<n;i*=2)
    {
        dob wn(cos(pi/i),sin(pi*o/i)),x,y;
        for (int j=0;j<n;j+=(i*2))
        {
            dob w(1,0);
            for (int k=0;k<i;k++,w*=wn)
            {
                x=a[j+k]; y=w*a[i+j+k];
                a[j+k]=x+y,a[i+j+k]=x-y;
            }
        }
    }
}
char s1[N],s2[N];
void query()
{
    l=0;
    for (n = 1; n <= m; n <<= 1) l++;
    for (int i=0;i<n;i++) r[i]=(r[i/2]/2)|((i&1)<<(l-1));
    fft(a,1),
    fft(b,1);
    for (int i=0;i<n;i++) a[i]*=b[i];
    fft(a,-1);
    for (int i=0;i<=m;i++) sum[i]=a[i].real()/n; 
}
int main()
{
    cin>>n; int tmp=n;
    for (int i=0;i<=n-1;i++) cin>>a[i];
    memcpy(a2,a,sizeof(a));
    for (int i=1;i<=n-1;i++) b[i]=1.0000000/i/i;
    n--;m=n*2;
    query();
    n=tmp;
    for (int i=0;i<=n-1;i++) 
      ans1[i+1]=sum[i];
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(sum,0,sizeof(sum));
    n=tmp;
    for (int i=0;i<n;i++) a[n-i-1]=a2[i];
  for (int i=1;i<=n-1;i++) b[i]=1.0000000/i/i;
    query();
  n=tmp;
  for (int i=0;i<=n-1;i++) ans1[i]-=sum[n-i];
  for (int i=1;i<=n;i++) printf("%.7f
",ans1[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/yinwuxiao/p/8597675.html