Codeforces 371D Vessels (模拟)
题目链接 Vessels
这道题我做得有点稀里糊涂啊==TLE了几发之后改了一行就A了。
具体思路就是记fi为若第i个容器已经盛不下水了,那么接下来盛水的那个容器。
hi为若现在要给i号容器加水,当前真正被加水的那个容器。
这样就大大降低了时间复杂度。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 #define rep(i,a,b) for(int i(a); i <= (b); ++i) 5 6 const int N = 200010; 7 long long a[N], b[N], f[N], h[N], c[N], d[N], op, x, cap, p; 8 int n, q, k; 9 10 int main(){ 11 12 scanf("%d", &n); 13 rep(i, 1, n) scanf("%lld", a + i); 14 a[n + 1] = 1e18; f[n + 1] = n + 1; h[n + 1] = n + 1; 15 rep(i, 1, n) b[i] = 0, f[i] = i + 1, h[i] = i, c[i] = 0; 16 scanf("%d", &q); 17 while (q--){ 18 scanf("%lld", &op); 19 if (op == 1){ 20 scanf("%d%lld", &k, &p); 21 while (p > 0){ 22 x = h[k]; int l = x, cnt = 0; 23 while (c[x]){ 24 d[++cnt] = x; 25 x = f[x]; 26 } 27 28 rep(i, 1, cnt){ 29 h[d[i]] = x; 30 f[d[i]] = x; 31 } 32 33 cap = a[x] - b[x]; 34 if (cap < p){ 35 b[x] = a[x]; 36 c[x] = 1; 37 p -= cap; 38 } 39 else b[x] += p, p = 0; 40 k = x; 41 } 42 } 43 else{ 44 scanf("%lld", &op); 45 printf("%lld\n", b[op]); 46 } 47 } 48 49 return 0; 50 51 }