UVALive 3938 "Ray, Pass me the dishes!"

来源:互联网 发布:电脑查询快捷键软件 编辑:程序博客网 时间:2024/06/05 00:10
求动态区间的最大连续和。

用线段树维护每个节点的前缀和,后缀和以及最大连续和。


代码:


#include<bits/stdc++.h>#define lson o<<1#define rson o<<1|1using namespace std;typedef long long ll;typedef pair<int, int> PII;const int MAXN = 5e5+5;struct node {    int pre, suf;    PII sub;    int l, r;}b[3*MAXN];int ql, qr;ll a[MAXN];ll sum(int l, int r) { return a[r]-a[l-1]; }ll sum(PII x) { return sum(x.first, x.second); }PII better(PII a, PII b) {    ll t1 = sum(a), t2 = sum(b);    if(t1 == t2) return a < b ? a : b;    return t1 < t2 ? b : a;}node maintain(node a, node b) {    node t;    t.l = a.l, t.r = b.r;    t.pre = better(make_pair(a.l, a.pre), make_pair(a.l, b.pre)).second;    t.suf = better(make_pair(a.suf, b.r), make_pair(b.suf, b.r)).first;    t.sub = better(better(a.sub, b.sub), make_pair(a.suf, b.pre));    return t;}void build(int o, int l, int r) {    if(l == r) {        b[o].pre = b[o].suf = l;        b[o].sub = make_pair(l, r);        b[o].l = b[o].r = l;        return;    }    int m = (l+r)>>1;    build(lson, l, m);    build(rson, m+1, r);    b[o] = maintain(b[lson], b[rson]);//    printf("??%d %d %d %d %d %d\n", l, r, b[o].pre, b[o].suf, b[o].sub.first, b[o].sub.second);}node query(int o, int l, int r) {    if(ql<=l && qr>=r) return b[o];    int m = (l+r)>>1;    if(ql<=m && qr>=m+1) return maintain(query(lson, l, m), query(rson, m+1, r));    if(ql <= m) return query(lson, l, m);    if(m+1 <= qr) return query(rson, m+1, r);}int main() {    int n, m, cas = 1;    while(~scanf("%d%d", &n, &m)) {        a[0] = 0;        for(int i = 1; i <= n; i++) {            int t; scanf("%d", &t);            a[i] = a[i-1]+t;        }        build(1, 1, n);        printf("Case %d:\n", cas++);        while(m--) {            scanf("%d%d", &ql, &qr);            node t = query(1, 1, n);            printf("%d %d\n", t.sub.first, t.sub.second);        }    }    return 0;}


0 0
原创粉丝点击