BZOJ 1011 遥远的行星

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的(可能还含有他人的代码成分)。
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<iostream>
 5 using namespace std;
 6 
 7 #define maxn (100010)
 8 #define esp (1e-7)
 9 double M[maxn],ans[maxn],sum[maxn],A; int n;
10 
11 inline void work()
12 {
13     for (int i = min(n,2000);i;--i)
14     {
15         int k = (int) (A*(double)i);
16         if (fabs((double)(k+1))/A-i<esp) ++k;
17         for (int j = 1;j <= k;++j)
18             ans[i] = ans[i]+M[i]*M[j]/(double)(i-j);
19     }
20     for (int i = 2001;i <= n;++i)
21     {
22         int k = (int)(A*(double)i),mid = (k+1) >> 1;
23         ans[i] = sum[k]*M[i]/(double)(i-mid);
24     }
25 }
26 
27 int main()
28 {
29     freopen("1011.in","r",stdin);
30     freopen("1011.out","w",stdout);
31     scanf("%d %lf",&n,&A); int i;
32     for (i = 1;i <= n;++i) scanf("%lf",M+i),sum[i] = sum[i-1] + M[i];
33     work();
34     for (int i = 1;i <= n;++i)
35         printf("%.8lf\n",fabs(ans[i]));
36     fclose(stdin); fclose(stdout);
37     return 0;
38 }
View Code

 

posted @ 2015-01-15 13:52  lmxyy  阅读(174)  评论(0编辑  收藏  举报