【BZOJ1011】[HNOI2008]遙遠的行星
阿新 • • 發佈:2019-03-20
spl zoj += clas scan max stream names class ,可知誤差不超過\(0.02\)。
【BZOJ1011】[HNOI2008]遙遠的行星
題面
bzoj
洛谷
題解
亂搞題。。。
主要是要利用“只要結果的相對誤差不超過5%即可”這個條件。
對於第\(i\)個行星,我們記\(x=\lfloor a*i\rfloor\),對他有貢獻的區間為\([1,x]\)。
我們統計時,將區間\([1,x]\)分塊統計,設塊大小為\(len\)。
當\(x\leq len\),暴力即可。
當\(x>T\),將\([1,x]\)分為很多小區間,則每個小區間\([x,y]\)的貢獻可看作
\[ \frac{M_i*\sum_{j=x}^yM_j}{i-\frac{x+y}{x}} \]
由於\(0.01<a\leq 0.35\)
代碼
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long double real; const int MAX_N = 1e5 + 5, LEN = 320; int N; real A, M[MAX_N], sum[MAX_N]; int main () { #ifndef ONLINE_JUDGE freopen("cpp.in", "r", stdin); #endif scanf("%d%Lf", &N, &A); for (int i = 1; i <= N; i++) scanf("%Lf", M + i); for (int i = 1; i <= N; i++) { sum[i] = sum[i - 1] + M[i]; real ans = 0; int r = i * A; for (int j = r; j > max(r - LEN, 0); j--) ans += M[i] * M[j] / (i - j); if (r > LEN) { r -= LEN; int t = sqrt(r), l; while (r) { l = max(r - t, 0); ans += M[i] * (sum[r] - sum[l]) / (i - (r + l) / 2); r = l; } } printf("%0.5Lf\n", ans); } return 0; }
【BZOJ1011】[HNOI2008]遙遠的行星