[2019.1.7]BZOJ1011 [HNOI2008]遥远的行星

首先,我们都会暴力计算贡献。

我们还发现这题对精度的要求很低。

于是我们心想,这一定不是出题人随便放的,而是关乎正解的。

我们发现当\(j-i\)很大时,它的微小改变对答案的影响就是微不足道的。

于是我们定义一个块大小\(siz\),然后对于一个长\(siz\)的区间\([i,i+siz-1]\),且这个区间位于影响\(F_j\)的取值的区间\([1,\lfloor Aj\rfloor]\)中,那么我们近似地认为它们的贡献之和为\(\frac{\sum_{x=i}^{i+siz-1}M_x}{\frac{1}{2}[(j-i)+(j-i-siz+1)]}\)

也就是我们认为一个区间的\(j-i\)都是其中\(j-i\)的平均值。然后如果要求影响第\(j\)颗星球引力的星球区间\([1,x]\)的引力和,我们对它分块计算,对于小于\(siz\)的区间暴力计算。

然后就过了。

code:

#include<bits/stdc++.h>
using namespace std;
const double _=1e-8;
const int blk=40;
int n,mx;
double a,m[100010],sum[100010];
double query(int l,int r,int f){
    if(r<l)return 0;
    double st=((f-l)*1.0+(f-r)*1.0)/2.0;
    return (sum[r]-sum[l-1])/st;
}
double query1(int l,int r,int f){
    if(r<l)return 0;
    double ans=0;
    for(int i=l;i<=r;i++)ans+=m[i]/(f-i*1.0);
    return ans;
}
double Query(int l,int r,int f){
    if(r<l)return 0;
    double ans=0;
    while(r-l+1>=blk)ans+=query(l,l+blk-1,f),l+=blk;
    ans+=query1(l,r,f);
    return ans;
}
int main(){
    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];
    for(int i=1;i<=n;i++)mx=i*a+_,printf("%.5lf\n",Query(1,mx,i)*m[i]);
    return 0;
}

转载于:https://www.cnblogs.com/xryjr233/p/BZOJ1011.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值