两种方法
1.二分每堆雪的消逝时间。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 100;
int n;
ll v[MAXN], t[MAXN], remain[MAXN], num[MAXN], sum[MAXN], pre[MAXN];
int main(void)
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%lld", &v[i]);
for(int i = 1; i <= n; i++) scanf("%lld", &t[i]), pre[i] = pre[i - 1] + t[i];
for(int i = 1; i <= n; i++){
int d = lower_bound(pre + 1, pre + 1 + n, v[i] + pre[i - 1]) - pre;
//printf("i = %d, d = %d\n", i, d);
num[i] += 1, num[d] -= 1;
remain[d] += v[i] + pre[i - 1] - pre[d - 1];
}
for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + num[i];
for(int i = 1; i <= n; i++){
ll ans = 0;
ans += sum[i] * t[i] + remain[i];
if(i - 1) printf(" "); printf("%lld", ans);
}printf("\n"); return 0;
}
2.也可以用优先队列解决。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 100;
int n;
ll v[MAXN], t[MAXN], pre[MAXN];
priority_queue<ll, vector<ll>, greater<ll> > q;
int main(void)
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%lld", &v[i]);
for(int i = 1; i <= n; i++) scanf("%lld", &t[i]), pre[i] = pre[i - 1] + t[i];
for(int i = 1; i <= n; i++){
ll ans = 0;
q.push(v[i] + pre[i - 1]);
while(!q.empty() && q.top() <= pre[i]){
ans += q.top() - pre[i - 1];
q.pop();
}
ans += t[i] * (ll)q.size();
if(i - 1) printf(" "); printf("%lld", ans);
}
return 0;
}