HDU 3954 Level up(线段树)
2012-07-22 13:26
429 查看
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int maxn = 10010; int t, n, k, qw; int need[11] = {0}; int maxexp[maxn<<2][11]; int add[maxn<<2]; void build(int l, int r, int rt) { for (int i = 1; i <= k; ++i) maxexp[rt][i] = -1; maxexp[rt][1] = 0; add[rt] = 0; if (l == r) return ; int m = (l + r) >> 1; build(l, m, rt << 1); build(m + 1, r, rt << 1 | 1); } void pushDown(int rt) { if (add[rt]) { add[rt<<1] += add[rt]; add[rt<<1|1] += add[rt]; for (int i = 1; i <= k; ++i) { if (maxexp[rt<<1][i] != -1) maxexp[rt<<1][i] += i * add[rt]; if (maxexp[rt<<1|1][i] != -1) maxexp[rt<<1|1][i] += i * add[rt]; } add[rt] = 0; } } void pushUp(int rt) { for (int i = 1; i <= k; ++i) { maxexp[rt][i] = max(maxexp[rt<<1][i], maxexp[rt<<1|1][i]); } } void levelUp(int l, int r, int rt) { if (l == r) { for (int i = 1; i < k; ++i) { if (maxexp[rt][i] != -1) { while (maxexp[rt][i] >= need[i+1] && i < k) { maxexp[rt][i+1] = maxexp[rt][i]; maxexp[rt][i] = -1; i++; } break; } } return ; } pushDown(rt); int m = (l + r) >> 1; for (int i = 1; i < k; ++i) { if (maxexp[rt<<1][i] >= need[i+1]) { levelUp(l, m, rt << 1); break; } } for (int i = 1; i < k; ++i) { if (maxexp[rt<<1|1][i] >= need[i+1]) { levelUp(m + 1, r, rt << 1 | 1); break; } } pushUp(rt); } void update(int l, int r, int L, int R, int e, int rt) { if (L <= l && R >= r) { add[rt] += e; for (int i = 1; i <= k; ++i) { if (maxexp[rt][i] != -1) { maxexp[rt][i] += i * e; } } for (int i = 1; i < k; ++i) { if (maxexp[rt][i] >= need[i+1]) { levelUp(l, r, rt); break; } } return ; } if (l == r) return ; pushDown(rt); int m = (l + r) >> 1; if (L <= m) update(l, m, L, R, e, rt << 1); if (R > m) update(m + 1, r, L, R, e, rt << 1 | 1); pushUp(rt); } int query(int l, int r, int L, int R, int rt) { if (L <= l && R >= r) { int ret = -1; for (int i = 1; i <= k; ++i) { ret = max(ret, maxexp[rt][i]); } return ret; } pushDown(rt); int m = (l + r) >> 1; int ret = -1; if (L <= m) ret = max(ret, query(l, m, L, R, rt << 1)); if (R > m) ret = max(ret, query(m + 1, r, L, R, rt << 1 | 1)); return ret; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); scanf("%d", &t); for (int cas = 1; cas <= t; ++cas) { printf("Case %d:\n", cas); scanf("%d%d%d", &n, &k, &qw); for (int i = 2; i <= k; ++i) { scanf("%d", &need[i]); } char op[3]; int li, ri, ei; build(1, n, 1); for (int i = 0; i < qw; ++i) { scanf("%s", op); if (op[0] == 'W') { scanf("%d%d%d", &li, &ri, &ei); update(1, n, li, ri, ei, 1); } else { scanf("%d%d", &li, &ri); printf("%d\n", query(1, n, li, ri, 1)); } } printf("\n"); } //system("pause"); return 0; }
相关文章推荐
- hdu 3954 线段树 Level up 很有特色的一个题(关于lazy操作)
- hdu 3954 Level up 线段树
- HDU 3954 Level up (线段树特殊懒惰标记)
- hdu 3954 Level up 线段树 升级版Lazy tag 区间整体的性质
- hdu 3954 level up 线段树区间维护
- hdu 3954 Level up(线段树进阶)
- HDU 3954 Level up(线段树)
- HDU 3954 Level up 2011 Alibaba Programming Contest 线段树
- HDU 3954 Level up 线段树
- hdu 3954 Level up(线段树)
- hdu 3954 Level up(线段树)
- HDU 3954 Level up(线段树的区间更新+小技巧)
- hdu 3954 Level up(线段树)
- hdu 3954 Level up (线段树)
- hdu 3954 Level up 线段树特殊更新节点
- HDU-3954:Level up(特殊的线段树成段更新)
- HDU 3954 Level up(线段树)
- HDU 3954 Level up (线段树)
- HDU 3954 Level up
- hdu 3954(线段树区间更新)