【Codeforces #470 Div. 2 C】Producing Snow

problem

Alice likes snow a lot! Unfortunately, this year’s winter is already over, and she can’t expect to have any more of it. Bob has thus bought her a gift — a large snow maker. He plans to make some amount of snow every day. On day i he will make a pile of snow of volume Vi and put it in her garden.

Each day, every pile will shrink a little due to melting. More precisely, when the temperature on a given day is Ti, each pile will reduce its volume by Ti. If this would reduce the volume of a pile to or below zero, it disappears forever. All snow piles are independent of each other.

Note that the pile made on day i already loses part of its volume on the same day. In an extreme case, this may mean that there are no piles left at the end of a particular day.

You are given the initial pile sizes and the temperature on each day. Determine the total volume of snow melted on each day.

Input
The first line contains a single integer N (1 ≤ N ≤ 105) — the number of days.

The second line contains N integers V1, V2, …, VN (0 ≤ Vi ≤ 109), where Vi is the initial size of a snow pile made on the day i.

The third line contains N integers T1, T2, …, TN (0 ≤ Ti ≤ 109), where Ti is the temperature on the day i.

Output
Output a single line with N integers, where the i-th integer represents the total volume of snow melted on day i.

Examples
inputCopy
3
10 10 5
5 7 2
outputCopy
5 12 4
inputCopy
5
30 25 20 15 10
9 10 12 4 13
outputCopy
9 20 35 11 25
Note
In the first sample, Bob first makes a snow pile of volume 10, which melts to the size of 5 on the same day. On the second day, he makes another pile of size 10. Since it is a bit warmer than the day before, the first pile disappears completely while the second pile shrinks to 3. At the end of the second day, he has only a single pile of size 3. On the third day he makes a smaller pile than usual, but as the temperature dropped too, both piles survive till the end of the day.


analysis

  • 第一次打cf……不是TX某游戏

  • 正解二分+线段树;题目大意不讲

  • 我们可以把每天的温度做前缀和,然后二分找出每一位彻底融化的那天的前一天

  • 然后线段树区间修改,给每一位 + 1 ,再给彻底融化的那天加上剩下要贡献的权值 v a l

  • 最后每一位答案就是 q u e r y ( 1 , 1 , n , i ) t [ i ] + v a l [ i ]

  • 时间复杂度 O ( n l o g 2 n )


code

#include<stdio.h>
#define MAXN 100001
#define fo(i,a,b) for (int i=a;i<=b;i++)

using namespace std;

long long v[MAXN],t[MAXN],pre[MAXN],val[MAXN];
long long tree[MAXN*4],lazy[MAXN*4];
int n;

long long read()
{
    long long x=0,f=1;
    char ch=getchar();

    while (ch<'0' || '9'<ch)
    {
        if (ch=='-')f=-1;
        ch=getchar();   
    }
    while ('0'<=ch && ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}

void downdata(int t)
{
    if (lazy[t])
    {
        lazy[t*2]+=lazy[t];
        lazy[t*2+1]+=lazy[t];
        tree[t]+=lazy[t];
        lazy[t]=0;
    }
}

void change(int t,int l,int r,int x,int y)
{
    if (x==l && r==y)
    {
        lazy[t]++;
        return;
    }
    downdata(t);
    int mid=(l+r)/2;
    if (y<=mid)change(t*2,l,mid,x,y);
    else if (x>mid)change(t*2+1,mid+1,r,x,y);
    else change(t*2,l,mid,x,mid),change(t*2+1,mid+1,r,mid+1,y);
    tree[t]=tree[t*2]+tree[t*2+1];
}

long long query(int t,int l,int r,int x)
{
    if (l==r)
    {
        downdata(t);
        return tree[t];
    }
    downdata(t);
    int mid=(l+r)/2;
    if (x<=mid)return query(t*2,l,mid,x);
    else return query(t*2+1,mid+1,r,x);
}

int main()
{
    n=read();
    fo(i,1,n)v[i]=read();
    fo(i,1,n)t[i]=read(),pre[i]=pre[i-1]+t[i];
    fo(i,1,n-1)
    {
        int l=i,r=n;
        while (l<=r)
        {
            int mid=(l+r)/2;
            if (pre[mid]-pre[i-1]>v[i])r=mid-1;
            else l=mid+1;
        }
        if (i<=r)change(1,1,n,i,r);
        val[r+1]+=v[i]-(pre[r]-pre[i-1]);
    }
    if (v[n]<t[n])val[n]+=v[n];
    else change(1,1,n,n,n);
    fo(i,1,n)printf("%I64d ",query(1,1,n,i)*t[i]+val[i]);
    printf("\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/enjoy_pascal/article/details/80909725