1011: [HNOI2008]遙遠的行星
阿新 • • 發佈:2018-04-12
queue getch getchar() HA inline efi LG online put
Submit: 5382 Solved: 2007
[Submit][Status][Discuss]
3
5
6
2
4
0.000000
0.000000
1.968750
2.976000
1011: [HNOI2008]遙遠的行星
Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 5382 Solved: 2007
[Submit][Status][Discuss]
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.33
5
6
2
4
Sample Output
0.0000000.000000
0.000000
1.968750
2.976000
HINT
精確結果應該為0 0 0 2 3,但樣例輸出的結果誤差不超過5%,也算對
這個題的方法真的玄學。。。很明顯我們發現需要枚舉每個行星,然後計算和加起來,但是這樣是n^2的復雜度很明顯不對,那麽我們還有什麽比較高科技的操作麽?線段樹?明顯不行。。平衡樹?貌似不是這類問題的方法吧。。。然後可以發現這題有special judge,嗯,根據我的判斷,估計應該有那種很2的代碼A掉。。看了看BZOJ的評測記錄,
好了,我估計AC代碼就是:
puts("-nan"); return 0;
交上去一看,果然A了。。。。
好了好了不扯這些,實際上這道題因為有了只要結果的相對誤差不超過5%即可.這句話,而且發現a的取值很小,所以我們大可以大膽的使用一些奇怪的方法,比如分塊。。。我們暴力計算一個自己確定的T值以內大小的數據,然後對於其它的大於T的,我們分成大小為T的幾塊,求出中間值得分母,然後代入式子就可以了,因為a很小,所在T取100時也不會超過5%的誤差。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include<cstdlib> #include <cmath> #include <string> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #include <set> #include <map> #define re register #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define mid ((i-j+i-j+len-1)*0.5) using namespace std; typedef long long ll; typedef unsigned long long ull; #define ms(arr) memset(arr, 0, sizeof(arr)) const int inf = 0x3f3f3f3f; ll a[100005],sum[100005],n; double ans[100005],A; inline int read() { int x=0,c=1; char ch=‘ ‘; while((ch>‘9‘||ch<‘0‘)&&ch!=‘-‘)ch=getchar(); while(ch==‘-‘) c*=-1,ch=getchar(); while(ch<=‘9‘&&ch>=‘0‘)x=x*10+ch-‘0‘,ch=getchar(); return x*c; } int main() { //freopen("date.in","r",stdin); n=read();scanf("%lf",&A); for(re int i=1;i<=n;i++){ a[i]=read(); sum[i]=sum[i-1]+a[i]; } for(re int i=1;i<=n;i++){ int lenth=int(A*i); if(lenth<=80){ for(re int j=1;j<=lenth;j++) ans[i]+=(a[i]*a[j])*1.0/(i-j); }else{ int len=lenth/80; for(re int j=len;j<=len*80;j+=len) ans[i]+=(sum[j]-sum[j-len])*a[i]*1.0/mid; for(re int j=len*80+1;j<=lenth;j++) ans[i]+=(a[i]*a[j])*1.0/(i-j); } } for(re int i=1;i<=n;i++) printf("%.10lf\n", ans[i]); return 0; }
很奇怪的是這代碼洛谷A了但是bzoj並沒有A掉。
1011: [HNOI2008]遙遠的行星