【BZOJ3527】[Zjoi2014]力
Description
给出n个数qi,给出Fj的定义如下:
![](http://www.lydsy.com/JudgeOnline/upload/201701/11.jpg)
令Ei=Fi/qi,求Ei.
Input
第一行一个整数n。
接下来n行每行输入一个数,第i行表示qi。
n≤100000,0<qi<1000000000
Output
n行,第i行输出Ei。与标准答案误差不超过1e-2即可。
Sample Input
5
4006373.885184
15375036.435759
1717456.469144
8514941.004912
1410681.345880
4006373.885184
15375036.435759
1717456.469144
8514941.004912
1410681.345880
Sample Output
-16838672.693
3439.793
7509018.566
4595686.886
10903040.872
3439.793
7509018.566
4595686.886
10903040.872
题解:对于上面的式子,我们将i<j和i>j分开计算
(感觉并没有推什么)
然后上面那个本身就是一个卷积,下面那个跟快速傅里叶之二一样,反转过来也是一个卷积,用FFT算出来后相减即可
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#define pi acos(-1.0)
#define z z
using namespace std;
struct cp
{
double x,y;
cp (double a,double b){x=a,y=b; }
cp (){}
cp operator + (cp a){return cp(x+a.x,y+a.y);}
cp operator - (cp a){return cp(x-a.x,y-a.y);}
cp operator * (cp a){return cp(x*a.x-y*a.y,x*a.y+y*a.x);}
}n1[1<<20],n2[1<<20];
double q[1<<20],a1[1<<20],a2[1<<20];
int n;
void init(cp *a,int len)
{
int i,j,t=0;
for(i=0;i<len;i++)
{
if(i>t) swap(a[i],a[t]);
for(j=(len>>1);(t^=j)<j;j>>=1);
}
}
void FFT(cp *a,int len,int f)
{
init(a,len);
int i,j,k,h;
cp t;
for(h=2;h<=len;h<<=1)
{
cp wn=cp(cos(f*2*pi/h),sin(f*2*pi/h));
for(j=0;j<len;j+=h)
{
cp w(1,0);
for(k=j;k<j+h/2;k++)
t=w*a[k+h/2],a[k+h/2]=a[k]-t,a[k]=a[k]+t,w=w*wn;
}
}
}
void work(cp *a,cp *b,double *c,int len)
{
FFT(a,len,1),FFT(b,len,1);
for(int i=0;i<len;i++) a[i]=a[i]*b[i];
FFT(a,len,-1);
for(int i=0;i<len;i++) c[i]=a[i].x/len;
}
int main()
{
scanf("%d",&n);
int i,j,len=1;
while(len<2*n) len<<=1;
for(i=0;i<n;i++) scanf("%lf",&q[i]);
for(i=0;i<n;i++) n1[i]=cp(q[i],0.0),n2[i]=cp(1.0/(i+1)/(i+1),0.0);
for(i=n;i<len;i++) n1[i]=cp(0.0,0.0),n2[i]=cp(0.0,0.0);
work(n1,n2,a1,len);
for(i=0;i<n;i++) n1[i]=cp(q[n-i-1],0.0),n2[i]=cp(1.0/(i+1)/(i+1),0.0);
for(i=n;i<len;i++) n1[i]=cp(0.0,0.0),n2[i]=cp(0.0,0.0);
work(n1,n2,a2,len);
printf("%.3f\n",-a2[n-2]);
for(i=1;i<n-1;i++) printf("%.3f\n",a1[i-1]-a2[n-i-2]);
printf("%.3f\n",a1[n-2]);
return 0;
}