forked from mpfeifer1/Kattis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreservoir.cpp
86 lines (69 loc) · 1.84 KB
/
reservoir.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll inf = (ll)1 << 60;
void solve() {
ll n;
cin >> n;
// Read input
vector<ll> locate(n+1);
vector<ll> height(n+1);
for(ll i = 1; i <= n; i++) cin >> locate[i];
for(ll i = 1; i <= n; i++) cin >> height[i];
// Prepare preprocessing
stack<pair<ll,ll>> prevheights;
prevheights.push({inf,-1});
vector<ll> needed(n+1,0); // Needed to fill, not overflow
// Run preprocessing
for(ll i = 1; i <= n; i++) {
// You'll need water from prev segments
needed[i] += needed[i-1];
ll currh = height[i];
ll currw = locate[i];
ll currl = 0;
while(true) {
ll prevh = prevheights.top().first;
ll prevw = prevheights.top().second;
// If our height is shorter
if(prevh > currh) {
ll h = (currh - currl);
ll w = (currw - prevw - 1);
needed[i] += w * h;
break;
}
// If our height is taller
ll h = (currh - currl);
ll w = (currw - prevw - 1);
needed[i] += w * h;
currl = max(prevh, currl);
currw = prevw + 1;
prevheights.pop();
}
// Add this wall to the stack of walls
prevheights.push({height[i],locate[i]});
}
// Debugging print
/*
for(auto i : needed) {
cout << i << " ";
}
cout << endl;
*/
// Run queries
ll q;
cin >> q;
while(q--) {
ll t;
cin >> t;
// Binary search on t, print answer
auto it = lower_bound(needed.begin(), needed.end(), t);
cout << max((int)distance(needed.begin(),it)-1,0) << endl;
}
}
int main() {
ll cases;
cin >> cases;
while(cases--) {
solve();
}
}