码迷,mamicode.com
首页 > 其他好文 > 详细

UVAlive - 3938 —— "Ray, Pass me the dishes!" 【线段树】

时间:2016-05-06 02:01:35      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

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!" 【线段树】

标签:

原文地址:http://www.cnblogs.com/AcIsFun/p/5463969.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!