http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=22105
#include <iostream> #include <cstdio> #include <cstring> #include <string> #define INF 0x3f3f3f3f #define lson rt<<1, l, m #define rson rt<<1|1, m+1, r using namespace std; typedef long long LL; const int MAXN = 524288 + 5; int n; struct P { LL d, sum, head, tail; int l, r, head_bound, tail_bound; } p[MAXN << 1]; void pushup(int rt) { int L = rt<<1, R = rt<<1|1; if(p[L].d >= p[R].d) { p[rt].d = p[L].d; p[rt].l = p[L].l; p[rt].r = p[L].r; } else { p[rt].d = p[R].d; p[rt].l = p[R].l; p[rt].r = p[R].r; } if(p[rt].d < p[L].tail + p[R].head) { p[rt].d = p[L].tail + p[R].head; p[rt].l = p[L].tail_bound; p[rt].r = p[R].head_bound; } else if(p[rt].d == p[L].tail + p[R].head) { if(p[rt].l > p[L].tail_bound) { p[rt].l = p[L].tail_bound; p[rt].r = p[R].head_bound; } else if(p[rt].l == p[L].tail_bound) { if(p[rt].r > p[R].head_bound) { p[rt].r = p[R].head_bound; } } } if(p[L].head >= p[L].sum + p[R].head) { p[rt].head = p[L].head; p[rt].head_bound = p[L].head_bound; } else { p[rt].head = p[L].sum + p[R].head; p[rt].head_bound = p[R].head_bound; } if(p[R].tail > p[R].sum + p[L].tail) { // 仔细斟酌一下,为了取最小下标,这里要取大于号 p[rt].tail = p[R].tail; p[rt].tail_bound = p[R].tail_bound; } else { p[rt].tail = p[R].sum + p[L].tail; p[rt].tail_bound = p[L].tail_bound; } p[rt].sum = p[L].sum + p[R].sum; } void build(int rt, int l, int r) { if(l == r) { scanf("%lld", &p[rt].d); p[rt].sum = p[rt].head = p[rt].tail = p[rt].d; p[rt].l = p[rt].r = p[rt].head_bound = p[rt].tail_bound = l; return; } int m = (l + r) >> 1; build(lson); build(rson); pushup(rt); } P query(int ql, int qr, int rt, int l, int r) { if(ql <= l && r <= qr) return p[rt]; int m = (l + r) >> 1; P left, right, ret; bool ok1 = 0, ok2 = 0; if(ql <= m) { left = query(ql, qr, lson); ok1 = 1; } if(qr > m) { right = query(ql, qr, rson); ok2 = 1; } if(ok1) { ret = left; if(ok2) { if(ret.d < right.d) { ret.d = right.d; ret.l = right.l; ret.r = right.r; } if(ret.d < left.tail + right.head) { ret.d = left.tail + right.head; ret.l = left.tail_bound; ret.r = right.head_bound; } else if(ret.d == left.tail + right.head){ if(ret.l > left.tail_bound) { ret.l = left.tail_bound; ret.r = right.head_bound; } else if(ret.l == left.tail_bound) { if(ret.r > right.head_bound) { ret.r = right.head_bound; } } } if(left.head >= left.sum + right.head) { ret.head = left.head; ret.head_bound = left.head_bound; } else { ret.head = left.sum + right.head; ret.head_bound = right.head_bound; } if(right.tail > right.sum + left.tail) { ret.tail = right.tail; ret.tail_bound = right.tail_bound; } else { ret.tail = right.sum + left.tail; ret.tail_bound = left.tail_bound; } ret.sum = left.sum + right.sum; } } else if(ok2) { ret = right; } return ret; } int main () { int m, a, b, kase=1; while(scanf("%d%d", &n, &m) != EOF) { build(1, 1, n); printf("Case %d:\n", kase++); // 注意Case的位置在这里,我把它写到了下面的while里面去了,WA到哭泣。。。 while(m--) { scanf("%d%d", &a, &b); P ans = query(a, b, 1, 1, n); printf("%d %d\n", ans.l, ans.r); } } return 0; }
UVAlive - 3938 —— "Ray, Pass me the dishes!" 【线段树】
时间: 2024-10-22 22:37:08