思路:详细分析见训练指南P200。注意可能答案的起点在左区间,终点在右区间
AC代码
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int maxn = 500000+5;
int dish[maxn];
LL psum[maxn];
LL sum(int l, int r) {
return psum[r] - psum[l-1];
}
LL sum(pii a) {
return psum[a.second] - psum[a.first-1];
}
pii better(pii a, pii b) {
if(sum(a) != sum(b)) return sum(a) > sum(b) ? a : b;
return a < b ? a : b;
}
struct node{
pii sub;
int prefix, suffix;
}tree[maxn<<2];
void build(int l, int r, int o) {
if(l == r) {
tree[o].sub = make_pair(l, l);
tree[o].prefix = tree[o].suffix = l;
return;
} else {
int mid = (l+r) / 2;
int lc = o*2, rc = o*2+1;
//创建子树
build(l, mid, lc);
build(mid+1, r, rc);
//递推prefix
LL v1 = sum(l, tree[lc].prefix);
LL v2 = sum(l, tree[rc].prefix);
if(v1 >= v2) {
tree[o].prefix = tree[lc].prefix;
} else {
tree[o].prefix = tree[rc].prefix;
}
//递推suffix
v1 = sum(tree[lc].suffix, r);
v2 = sum(tree[rc].suffix, r);
if(v1 >= v2) {
tree[o].suffix = tree[lc].suffix;
} else {
tree[o].suffix = tree[rc].suffix;
}
//递推sub
tree[o].sub = better(tree[lc].sub, tree[rc].sub);
tree[o].sub = better(tree[o].sub, make_pair(tree[lc].suffix, tree[rc].prefix));
}
}
int qL, qR;
pii query_prefix(int o, int l, int r) {
if(tree[o].prefix <= qR) return make_pair(l, tree[o].prefix);
int mid = (l+r)/2;
int lc = o*2, rc = o*2+1;
if(qR <= mid) {
return query_prefix(lc, l, mid);
} else {
pii i = query_prefix(rc, mid+1, r);
i.first = l;
return better(i, make_pair(l, tree[lc].prefix));
}
}
pii query_suffix(int o, int l, int r) {
if(tree[o].suffix >= qL) return make_pair(tree[o].suffix, r);
int mid = (l+r)/2;
int lc = o*2, rc = o*2+1;
if(qL >= mid+1) {
return query_suffix(rc, mid+1, r);
} else {
pii i = query_suffix(lc, l, mid);
i.second = r;
return better(i, make_pair(tree[rc].suffix, r));
}
}
pii query(int o, int l, int r) {
if(qL <= l && r <= qR) return tree[o].sub;
int mid = (l+r)/2;
int lc = o*2, rc = o*2+1;
if(qR <= mid) return query(lc, l, mid);
if(qL > mid) return query(rc, mid+1, r);
pii i1 = query_prefix(rc, mid+1, r); //右半的前缀
pii i2 = query_suffix(lc, l, mid); //左半的后缀
pii i3 = better(query(lc, l, mid), query(rc, mid+1, r));
return better(i3, make_pair(i2.first, i1.second));
}
int main() {
int n, m, kase = 1;
while(scanf("%d%d", &n, &m) == 2) {
psum[0] = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &dish[i]);
psum[i] = psum[i-1] + dish[i];
}
build(1, n, 1);
printf("Case %d:\n", kase++);
for(int i = 0; i < m; i++) {
scanf("%d%d", &qL, &qR);
pii ans = query(1, 1, n);
printf("%d %d\n", ans.first, ans.second);
}
}
return 0;
}
如有不当之处欢迎指出!