第一次见到拿误差做文章的题,世界观又一次刷新。
看到这题的第一感觉是前两天做过的力,所以一来就往FFT上想。。。然并卵,边界死活不会处理
看了标解顿时有婊人的冲动。。。
对于那些比较大的n(以2000为界比较合适),我们发现不同1/(i-j)之间的差距极小,因此我们用1/(i-(i*A)/2)来代替所有的分母,加上前缀和就变成O(1)了。
/**************************************************************
Problem: 1011
User: RicardoWang
Language: C++
Result: Accepted
Time:1580 ms
Memory:3616 kb
****************************************************************/
#include<cstdlib>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define maxn 100005
int n;
double a[maxn],A,m[maxn];
void _read(int &x)
{
x=0; char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return ;
}
void _readLL(long long &x)
{
x=0; char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return ;
}
void Init()
{
long long x; _read(n);
scanf("%lf",&A);
for(int i=1;i<=n;i++){_readLL(x); m[i]=x;a[i]=a[i-1]+m[i];}
return ;
}
double g[maxn],eps=1e-7;
double fabs(double x)
{
return x>0? x:-x;
}
int main()
{
//freopen("in.txt","r",stdin);
Init();
int j;
memset(g,0,sizeof(g));
for(int i=1;i<=2000 && i<=n;i++)
{
j=(int)(A*(double)i);
if(fabs(A*(double)i-(double)(j+1))<=eps)j++;
for(int k=1;k<=j;k++)g[i]+=m[i]*m[k]/(double)(i-k);
}
for(int i=2001;i<=n;i++)
{
j=(int)(A*i);
/* while(j>10000)
{
g[i]+=m[i]*(a[j]-a[j-10000])/(double)(i-j-5000); j-=10000;
}
while(j>1000)
{
g[i]+=m[i]*(a[j]-a[j-1000])/(double)(i-j-500); j-=1000;
}*/
g[i]+=m[i]*(a[j])/(double)(i-j/2);
}
for(int i=1;i<=n;i++)
{
printf("%lf\n",g[i]);
}
return 0;
}