【BZOJ1011】[HNOI2008]遥远的行星

【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; 
} 

转载于:https://www.cnblogs.com/heyujun/p/10561968.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值