1011: [HNOI2008]遥远的行星
Description
直线上N颗行星,X=i处有行星i,行星J受到行星I的作用力,当且仅当i<=AJ.此时J受到作用力的大小为 Fi->j=Mi*Mj/(j-i) 其中A为很小的常量,故直观上说每颗行星都只受到距离遥远的行星的作用。请计算每颗行星的受力,只要结果的相对误差不超过5%即可.
Input
第一行两个整数N和A. 1<=N<=10^5.0.01< a < =0.35,接下来N行输入N个行星的质量Mi,保证0<=Mi<=10^7
Output
N行,依次输出各行星的受力情况
Sample Input
5 0.3
3
5
6
2
4
Sample Output
0.000000
0.000000
0.000000
1.968750
2.976000
HINT
精确结果应该为0 0 0 2 3,但样例输出的结果误差不超过5%,也算对
【解题报告】
这题有毒
令
i=⌊aj⌋
对
于星球
j
,我们要求的和式为
当
j
很大时,
用
sumi
表示前
i
个星球的质量和,那么和式可以化成
这样我们就可以少用一个变量k,复杂度就降为了O(n)
代码如下:
/**************************************************************
Problem: 1011
User: onepointo
Language: C++
Result: Accepted
Time:1676 ms
Memory:2384 kb
****************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100010
int n;
double a,ans;
double m[N],sum[N];
int main()
{
scanf("%d%lf",&n,&a);
for(int j=1;j<=n;++j)
{
int i=(int)(a*j+1e-8);
scanf("%lf",m+j);
ans=0;
if(j<=500)
for(int k=1;k<=i;++k)
ans+=m[k]*m[j]/(j-k);
else ans=sum[i]*m[j]/(j-i/2);
printf("%lf\n", ans);
sum[j]=sum[j-1]+m[j];
}
return 0;
}