BZOJ 1011 遥远的行星

时间:2025-03-27 19:03:13

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%,也算对

据说是道逗B题,但我还是不会写,看到结论copy的(可能还含有他人的代码成分)。
 #include<cstdio>
#include<cstdlib>
#include<cmath>
#include<iostream>
using namespace std; #define maxn (100010)
#define esp (1e-7)
double M[maxn],ans[maxn],sum[maxn],A; int n; inline void work()
{
for (int i = min(n,);i;--i)
{
int k = (int) (A*(double)i);
if (fabs((double)(k+))/A-i<esp) ++k;
for (int j = ;j <= k;++j)
ans[i] = ans[i]+M[i]*M[j]/(double)(i-j);
}
for (int i = ;i <= n;++i)
{
int k = (int)(A*(double)i),mid = (k+) >> ;
ans[i] = sum[k]*M[i]/(double)(i-mid);
}
} int main()
{
freopen("1011.in","r",stdin);
freopen("1011.out","w",stdout);
scanf("%d %lf",&n,&A); int i;
for (i = ;i <= n;++i) scanf("%lf",M+i),sum[i] = sum[i-] + M[i];
work();
for (int i = ;i <= n;++i)
printf("%.8lf\n",fabs(ans[i]));
fclose(stdin); fclose(stdout);
return ;
}