CodeForces - 948C Producing Snow(前缀和+区间更新)

题目链接

题意:每天造一堆雪a[i],每天每堆雪会融化b[i],问第i天总共融化了多少雪;

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;

const int maxn = 1e5+10;
ll a[maxn];//第i天堆的雪的大小
ll b[maxn];//第i天的温度,每堆雪融化的量
ll c[maxn];//温度的前缀和
ll d[maxn];//第i天还剩几堆雪
ll e[maxn];//如果某堆雪的大小小于第i天的温度,不够d中的1,就把他保存在e数组里

int main()
{
    int n;
    while(cin>>n){
        memset(a,0,sizeof(a));//初始化
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        memset(d,0,sizeof(d));
        memset(e,0,sizeof(e));
        for(int i = 1;i <= n;i++) cin>>a[i];
        for(int i = 1;i <= n;i++){
            cin>>b[i];
            c[i] = c[i-1]+b[i];
        }
/*
如果第i堆雪能存在k天(刚好在第k天融化完),即i到k+i-1天都存在,我们把d[i]赋值为1,d[i+k]赋值为-1,计算的时候每个d[i]都加上d[i-1]的数量,即d[i]到d[i+k-1]的值都是1,d[i+k]的值为0,(1+(-1)=0),这样就完成了区间更新
*/
        for(int i = 1;i <= n;i++){
            d[i] += 1;//很多个区间,区间之间的值叠加,所以是d[i]+=1,而不是d[i]=1;
            int l = lower_bound(c,c+n+1,c[i-1]+a[i])-c;//找到融化的那一天
            if(c[l]==c[i-1]+a[i]) d[l+1]-=1;//如果刚好融化,处理完d数组就ok了
            else if(c[l]>c[i-1]+a[i]){
                d[l]-=1;//同理,区间叠加
                e[l] += (b[l]-(c[l]-c[i-1]-a[i]));//不能刚好融化,把多余的数量保存在e数组里
            }
        }
        for(int i = 1;i <= n;i++){
            d[i]+=d[i-1];//处理d数组
            cout<<d[i]*b[i]+e[i]<<' ';
        }
        cout<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42754600/article/details/81738548