CF948C Producing Snow
Description
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 ≤ 10^5)\) — the number of days.
The second line contains \(N\) integers \(V1, V2, ..., VN (0 ≤ Vi ≤ 10^9)\), 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 ≤ 10^9)\), 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
3
10 10 5
5 7 2
output
5 12 4
input
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.
My Solution
很容易想到暴力求解,即循环N次,然后遍历所有数,一个一个减去\(Ti\)。但是考虑到这题数据范围偏大,所以\(O(N^2)\)是肯定不行的。
此时想到堆,建立一个小根堆,然后从中选最小的数,减去\(Ti\),如果减去后小于等于0则使其出队,继续找最小;否则则代表这个数和其他所有数都不会减去这个数后小于等于0,循环即可停止。
但是我们通过堆只处理了会被\(Ti\)减去后小于等于0的雪堆,而剩下堆中的\(tot\)个雪堆不会被消耗干净,所以他们对答案的贡献是\(Ti*tot\),因为这\(tot\)个雪堆都会被减去\(Ti\)且不会为0
但是还有一个问题,即这些雪堆被减去后,他们的值应该发生变化,所以想到开一个循环把这些数全部减去\(Ti\),但是显然不行,算法又退化到\(O(N^2)\)
所以我不减去他们,而是给后面入队的数加上\(Ti\),这样他们的相对大小关系并不会改变,只需要在最后算答案的时候减掉就行了。
#include <cstdio>
int N,tot=0;
long long V[100005];
long long H[100005];
inline long long read(){
long long num=0;char ch=getchar();
while(ch>'9'||ch<'0')ch=getchar();
while(ch>='0'&&ch<='9')num=num*10+ch-48,ch=getchar();
return num;
}
inline void write(long long x){
if(x>9)write(x/10);
putchar(x%10+48);
}
inline void up(int i){
while(i>1){
int j = i>>1;
if(H[i]<H[j]){
long long t = H[i];
H[i] = H[j];
H[j] = t;
i=j;
}
else break;
}
}
inline void down(int i){
while((i<<1)<=tot){
int j = i<<1;
if(j<tot&&H[j]>H[j+1])j++;
if(H[i]>H[j]){
long long t = H[i];
H[i] = H[j];
H[j] = t;
i=j;
}
else break;
}
}
int main(){
scanf("%d",&N);
for(register int i=1;i<=N;++i)V[i]=read();
int w;
long long sum = 0;
for(register int i=1;i<=N;++i){
long long ans = 0;
tot++;H[tot]=V[i]+sum;up(tot);
w=read();
while(tot>0&&H[1]-sum<=w){
ans += H[1]-sum;
H[1]=H[tot--];down(1);
}
if(tot>0)sum+=w;
ans += (long long)tot*w;
write(ans);putchar(' ');
}
return 0;
}
CF`s Solution
以下是原文
We can directly simulate the process, but it takes \(O(N^2)\) time, which is too slow. There are multiple approaches how to make this simulation faster. We present two of them.
- In the first solution, instead of calculating the total volume of the snow melted, we first calculate two quantities: \(F[i]\) — the number of piles left after day \(i\), and M[i] — the total volume of piles that disappear on day \(i\).The answer will then be \(F[i] * T[i] + M[i]\).
Calculate prefix sums of the temperatures. This way, when a snow pile is formed on day \(i\), we can use binary search to determine on which day it will disappear completely. Denote this day by \(j\) and put \(j = N + 1\) if the pile survives. We can note that on every day \(k\) between \(i\) and \(j - 1\) inclusive, this pile will lose \(T[k]\) of its volume, which corresponds to increasing \(F[k]\) by one. Furthermore, we add the remaining volume to \(M[j]\).To calculate all \(F[i]\)'s fast, we can again use prefix sums — adding 1 to interval can then be done by two additions.