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
3
5
6
2
4
Sample Output
0.000000
0.000000
0.000000
1.968750
2.976000
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 ",fabs(ans[i])); 36 fclose(stdin); fclose(stdout); 37 return 0; 38 }