ARC 072 F - 单调队列

题目大意: 有个水库,最多能存L单位水,一开始是空的,对于n天,每天早上有v[i]单位的,水温为t[i]的水流进来。每天晚上你可以放掉一些水,多少自定。但是必须保证第二天水库不会溢出。现在问,对于每个i,在使用最优放水策略的情况下,第i天水库是满的情况下最高水温(i之间互相独立)。混合后的温度计算就和混合溶液浓度一样计算。 n<=1e5,其他数1e9范围内 。
题解:改用金属的密度、体积和质量来描述。考虑现在要只留下体积L-v的金属,那么多余的金属一定是之前就别加进来。也就是你可以不加之前的金属,但是只要之前的金属没摘干净现在的金属就不能摘出去。因此贪心维护当前金属组成,每次把多余的密度最小的那些摘除去,然后把当前的混和进去。如果当前的密度比加之前的组成里面最大的密度还要大那么就意味着之后可以在不动当前这个得情况下摘除这些东西;否则就一路和并下去,意味着要摘除当前的金属,连带着这些也要摘除。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define N 500010
#define db long double
#define lint long long
#define gc getchar()
using namespace std;
inline int inn()
{
   int x,ch;while((ch=gc)<'0'||ch>'9');
   x=ch^'0';while((ch=gc)>='0'&&ch<='9')
   	x=(x<<1)+(x<<3)+(ch^'0');return x;
}
int vs,qv[N],fp,rp;db qr[N],qm[N],ms;
int main()
{
   int n=inn(),L=inn();fp=1,rp=0,vs=0,ms=0;
   rep(i,1,n)
   {
   	int r=inn(),v=inn(),vr;db m=(db)v*r,mr;
   	while(fp<=rp&&vs>L-v)
   		vr=min(vs-(L-v),qv[fp]),
   		qv[fp]-=vr,vs-=vr,mr=vr*qr[fp],
   		qm[fp]-=mr,ms-=mr,fp+=(qv[fp]==0);
   	rp++,vs+=(qv[rp]=v),ms+=(qm[rp]=m),qr[rp]=r;
   	while(fp<rp&&qr[rp]<=qr[rp-1])
   		qm[rp-1]+=qm[rp],qv[rp-1]+=qv[rp],
   		qr[rp-1]=qm[rp-1]/qv[rp-1],rp--;
   	printf("%.10lf\n",(double)(ms/vs));
   }
   return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值