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 }

 

posted @ 2017-01-31 20:36  cxhscst2  阅读(285)  评论(0编辑  收藏  举报