Codeforces Round #470/923B/947B Producing Snow 【线段树,二分,前缀和】

C. Producing Snow
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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
input
Copy
3
10 10 5
5 7 2
output
5 12 4
input
Copy
5
30 25 20 15 10
9 10 12 4 13
output
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.

 

 做法:

通过前缀和二分查找,找到能第i堆雪的被融化完的天数j

然后第j天温度肯定要融化第i堆雪剩下的部分

通过线段树记录,b[i]温度能够完全融化多少堆雪,这里完全融化的意思是b[i]温度充分被利用

区间更新第i天和第j-1天的温度融化数

最后统一更新答案即可

 

代码:
  1 #include<iostream>
  2 using namespace std;
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<cstdlib>
  6 const int MAXN = 1100000;
  7 typedef long long LL;
  8 template<class T>
  9 class tree{
 10     public:
 11     int ws;
 12     T a[MAXN];
 13     T gg[MAXN];
 14     int l[MAXN],r[MAXN];
 15     void creat(int k,int ll,int rr){
 16         l[k]=ll;r[k]=rr;
 17         if(ll>=rr){
 18             a[k]=0;
 19             gg[k]=0;
 20             return;
 21         }
 22         int mid=(ll+rr)/2; 
 23         creat(k*2,ll,mid);
 24         creat(k*2+1,mid+1,rr);
 25         a[k]=a[k*2]+a[k*2+1];
 26         gg[k]=0;
 27     }
 28     void change(int k,int ll,int rr,int t){
 29         if(gg[k]!=0){
 30             a[k]+=gg[k]*(r[k]-l[k]+1);
 31             if(l[k]!=r[k]){
 32                 gg[k*2]+=gg[k];
 33                 gg[k*2+1]+=gg[k];
 34             }
 35             gg[k]=0;
 36         }
 37         if(ll>r[k]||rr<l[k]) return;
 38         if(ll<=l[k]&&rr>=r[k]){
 39             a[k]+=(r[k]-l[k]+1)*t;
 40             if(l[k]!=r[k]){
 41                 gg[k*2]+=t;
 42                 gg[k*2+1]+=t;
 43             }
 44             return;
 45         }
 46         change(k*2,ll,rr,t);
 47         change(k*2+1,ll,rr,t);
 48         a[k]=a[k*2]+a[k*2+1];
 49     }
 50     T query(int k,int ll,int rr){
 51         if(gg[k]!=0){
 52             a[k]+=(r[k]-l[k]+1)*gg[k];
 53             if(l[k]!=r[k]){
 54                 gg[k*2]+=gg[k];
 55                 gg[k*2+1]+=gg[k];
 56             }
 57             gg[k]=0;
 58         }
 59         if(ll>r[k]||rr<l[k]) return 0; 
 60         if(ll<=l[k]&&rr>=r[k]){
 61             return a[k];
 62         }
 63         int ans1=query(k*2,ll,rr);
 64         int ans2=query(k*2+1,ll,rr);
 65         a[k] = ans1 + ans2;
 66         return ans1+ans2;    
 67     }
 68 };
 69 tree<LL> t; 
 70 LL a[MAXN],b[MAXN];
 71 int bin_search(int x,int y,LL key){
 72     int l = x,r = y;
 73     while(l<=r){
 74         int mid = (l+r)/2;
 75         if(b[mid]<key)
 76             l = mid + 1;
 77         else
 78             r = mid -1;
 79     }
 80     return l;
 81 }
 82 LL ans[MAXN];
 83 int main(){
 84     int n;
 85     scanf("%d",&n);
 86     t.creat(1,1,n);
 87     for(int i=1;i<=n;i++)
 88         scanf("%I64d",&a[i]);
 89     for(int i=1;i<=n;i++){
 90         scanf("%I64d",&b[i]);
 91         b[i]+=b[i-1];
 92     }
 93     for(int i=1;i<=n;i++){
 94         a[i]+=b[i-1];
 95         int j = bin_search(i,n,a[i]);//二分查找第j天之后第i堆雪就没了 
 96         t.change(1,i,j-1,1);//区间更新第i天到第j-1天的融化雪的堆数,即这些天剩下的体积大于等于当前最大温度的天数
 97         ans[j] += a[i] - b[j-1];//更新第j天的答案,加上第j天融化的剩余的第i堆雪的重量 
 98     }
 99     for(int i=1;i<=n;i++){
100         ans[i] += t.query(1,i,i)*(b[i]-b[i-1]);//加上第i天能完全融化的雪的堆数 
101     }
102     for(int i=1;i<=n;i++)
103         printf("%I64d ",ans[i]);
104     return 0;
105 }

 

转载于:https://www.cnblogs.com/xfww/p/8543482.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值