首页 > 其他 > 详细

【BZOJ1011】[HNOI2008]遥远的行星

时间:2019-03-19 23:30:40      阅读:114      评论:0      收藏:0      [点我收藏+]

【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\),可知误差不超过\(0.02\)

代码

#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]遥远的行星

原文:https://www.cnblogs.com/heyujun/p/10561968.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!