UVALive

来源:互联网 发布:北京游戏公司排名知乎 编辑:程序博客网 时间:2024/06/15 16:07

思路:详细分析见训练指南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;}

如有不当之处欢迎指出!