思路很清晰,实现很繁琐。分析过程可以参考LRJ,自己的总结晚些放。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxN=5e5+5,maxNode=1e6+5; #define ll long long #define Seg pair<int,int> #define fi first #define se second #define lson l,m,rt*2 #define rson m+1,r,rt*2+1 ll prefix_sum[maxN]; ll sum(int L, int R) {return prefix_sum[R] - prefix_sum[L - 1];} ll sum(Seg p) {return sum(p.fi, p.se);} Seg better(Seg a, Seg b) { if (sum(a) != sum(b)) return sum(a) > sum(b) ? a : b; else return a < b ? a : b; } int qL, qR; struct SegTree { int max_prefix[maxNode]; int max_suffix[maxNode]; Seg max_sub[maxNode]; void build(int l, int r, int rt) { if (l == r) { max_prefix[rt] = max_suffix[rt] = l; max_sub[rt] = make_pair(l, l); return; } int m = l + (r - l) / 2; int lch = rt * 2, rch = rt * 2 + 1; build(lson); build(rson); // push_up // 递推max_prefix ll v1 = sum(l, max_prefix[lch]); ll v2 = sum(l, max_prefix[rch]); if (v1 == v2) max_prefix[rt] = min(max_prefix[lch], max_prefix[rch]); else max_prefix[rt] = v1 > v2 ? max_prefix[lch] : max_prefix[rch]; // 递推max_suffix v1 = sum(max_suffix[lch], r); v2 = sum(max_suffix[rch], r); if (v1 == v2) max_suffix[rt] = min(max_suffix[lch], max_suffix[rch]); else max_suffix[rt] = v1 > v2 ? max_suffix[lch] : max_suffix[rch]; // 递推max_sub max_sub[rt] = better(max_sub[lch], max_sub[rch]); max_sub[rt] = better(max_sub[rt], make_pair(max_suffix[lch], max_prefix[rch])); } Seg query_prefix(int l, int r, int rt) { if (max_prefix[rt] <= qR) return make_pair(l, max_prefix[rt]); int m = (l + r) / 2; int lch = rt * 2; if (qR <= m) return query_prefix(lson); Seg i = query_prefix(rson); i.fi = l; return better(i, make_pair(l, max_prefix[lch])); } Seg query_suffix(int l, int r, int rt) { if (max_suffix[rt] >= qL) return make_pair(max_suffix[rt], r); int m = (l + r) / 2; int rch = 2 * rt + 1; if (qL > m) return query_suffix(rson); Seg i = query_suffix(lson); i.se = r; return better(i, make_pair(max_suffix[rch], r)); } Seg query(int l, int r, int rt) { if (qL <= l && r <= qR) return max_sub[rt]; int m = (l + r) / 2; if (qR <= m) return query(lson); if (qL > m) return query(rson); Seg i1 = query_prefix(rson); Seg i2 = query_suffix(lson); Seg i3 = better(query(lson), query(rson)); return better(make_pair(i2.fi, i1.se), i3); } }; SegTree tree; int main() { // freopen("data.in", "r", stdin); int kase = 0, n, a, Q; while (~scanf("%d%d", &n, &Q)) { prefix_sum[0] = 0; for (int i = 0; i < n; ++i) { scanf("%d", &a); prefix_sum[i + 1] = prefix_sum[i] + a; } tree.build(1, n, 1); printf("Case %d: ", ++kase); while (Q--) { int L, R; scanf("%d%d", &L, &R); qL = L, qR = R; Seg ans = tree.query(1, n, 1); printf("%d %d ", ans.fi, ans.se); } } return 0; }