目录
一. 问题描述
Problem Description
有n天,每天造一堆雪,体积为v[i], 每天雪消融体积为t[i] , (前一天没有消融完的雪会留到下一天),问每天消融的雪的总体积。
二. 题解代码
优先队列 + 思维。第k天产生的雪堆,在第i天剩余体积是 v[k] + sum[k-1] - sum[i] , 我们首先假设每天消融的体积是 ans = t * t[i](也就是每一堆雪都没有融化完),那如果真的所有雪都没有融化完,那今天消融的就是ans; 但是如果有雪融化完了,那肯定从最小的一堆开始判断,那这堆雪比我们计算的多融化了 v[k] + sum[k-1] - sum[i] ,我们就要在ans里面减去这个多融化的。(其实应该是加上,因为那个值是负的) , 删掉这堆雪依次判断下一堆。
因此在实现时,我们这里用优先队列维护,每天插入v[i] + sum[i-1](用于减去差值,其中sum[i]是每天消融雪的前缀和) ,然后在队列里面判断维护即可。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 100000 + 5;
typedef long long int LL;
LL val[maxn];
LL day[maxn];
LL sum[maxn];
int main()
{
int n;
scanf("%d",&n);
sum[0] = 0;
for(int i = 1;i<=n;i++){
scanf("%lld",&val[i]);
}
for(int j = 1;j<=n;j++){
scanf("%lld",&day[j]);
sum[j] = sum[j-1] + day[j];//前缀和
}
priority_queue<LL,vector<LL>,greater<LL> >que;
for(int i = 1;i<=n;i++){
que.push(val[i] + sum[i-1]);//插入今天数据
LL ans = que.size()*day[i];//今天假设的总消融体积
while(!que.empty()&&que.top()<=sum[i]){//判断多消融的体积
ans+=(que.top() - sum[i]);
que.pop();
}
if(i==1)printf("%lld",ans);
else printf(" %lld",ans);
}
printf("\n");
return 0;
}