题目链接:http://codeforces.com/contest/948
思路:用前缀和pre[i]储存前i天的温度t之和,再用c[i]表示第i个雪堆虚拟的大小(v[i] +pre[i-1]),这样就可以利用pre[]的单调性在O(logn)的时间复杂度内找出第i个雪堆融化完的那天(记下标为index),这时需要做两件事:
1,ans[i]++,ans[index]--
2,add[index] += 第i个雪堆在第index天的融化量
最后用前缀数组的特性,算出第i天会融化几个雪堆乘温度t,再加上add[i],即为最终答案。
/*****
by x w d
******/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 500;
ll n;
ll v[maxn],t[maxn],pre[maxn],c[maxn];
ll ans[maxn],add[maxn];
int main()
{
//freopen("DATA.c", "r", stdin);
ios::sync_with_stdio(false); cin.tie();cout.tie();
cin>>n;
for(int i = 1; i <= n; i ++) cin>>v[i];
for(int i = 1; i <= n; i ++) cin>>t[i], pre[i] = pre[i-1] + t[i];
for(int i = 1; i <= n; i ++) c[i] = pre[i-1] + v[i];
for(int i = 1; i <= n; i ++){
int index = lower_bound(pre+1,pre+n+1,c[i]) - pre;
ans[i] += 1;
ans[index] -= 1;
add[index] += (c[i] - pre[index-1]);
}
for(int i = 1; i <= n; i ++) ans[i] = ans[i] + ans[i-1];
for(int i = 1; i <= n; i ++){
cout<<ans[i]*t[i] + add[i]<<" ";
}
return 0;
}