您的位置:首页 > 理论基础 > 数据结构算法

UVA live 3938 - "Ray, Pass me the dishes!"(线段树)

2016-08-27 18:23 393 查看
题目链接:点击打开链接

该题需要深刻理解线段树的特点:任意一个父结点所表示的区间都是两个儿子区间的并, 且儿子区间的交为空集。

那么我们可以采用分治的思想: 一段区间的最大连续和要么来自左半边, 要么来自右半边, 或者一半在左一半在右。

细节参见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const ll INF = (ll)1e15;
const int maxn = 300000+10;
int T,n,A,B,m;
struct node {
ll v;
int l, r;
node(ll v=0, int l=0, int r=0): v(v), l(l), r(r) {}
}maxv[maxn<<2], pre[maxn<<2], last[maxn<<2], sum[maxn<<2];
void push_up(int l, int r, int o) {
maxv[o] = maxv[o<<1];
if(maxv[o].v < maxv[o<<1|1].v) maxv[o] = maxv[o<<1|1];
if(maxv[o].v < last[o<<1].v + pre[o<<1|1].v) maxv[o]=node(last[o<<1].v+pre[o<<1|1].v, last[o<<1].l,pre[o<<1|1].r);
else if(maxv[o].v == last[o<<1].v + pre[o<<1|1].v) {
if(maxv[o].l > last[o<<1].l) maxv[o]=node(last[o<<1].v+pre[o<<1|1].v, last[o<<1].l,pre[o<<1|1].r);
else if(maxv[o].l == last[o<<1].l) {
if(maxv[o].r > pre[o<<1|1].r) maxv[o]=node(last[o<<1].v+pre[o<<1|1].v, last[o<<1].l,pre[o<<1|1].r);
}
}
pre[o] = pre[o<<1];
if(pre[o].v < sum[o<<1].v + pre[o<<1|1].v) pre[o] = node(sum[o<<1].v + pre[o<<1|1].v, sum[o<<1].l, pre[o<<1|1].r);
else if(pre[o].v == sum[o<<1].v + pre[o<<1|1].v) {
if(pre[o].r > pre[o<<1|1].r) pre[o] = node(sum[o<<1].v + pre[o<<1|1].v, l, pre[o<<1|1].r);
}
last[o] = last[o<<1|1];
if(last[o].v < last[o<<1].v + sum[o<<1|1].v) last[o] = node(last[o<<1].v + sum[o<<1|1].v, last[o<<1].l, r);
else if(last[o].v == last[o<<1].v + sum[o<<1|1].v) {
if(last[o].l > last[o<<1].l) last[o] = node(last[o<<1].v + sum[o<<1|1].v, last[o<<1].l, r);
}
sum[o] = node(sum[o<<1].v + sum[o<<1|1].v, sum[o<<1].l, sum[o<<1|1].r);
}
void build(int l, int r, int o) {
int m = (l + r) >> 1;
maxv[o].v = pre[o].v = last[o].v = sum[o].v = -INF;
if(l == r) {
scanf("%lld", &maxv[o].v);
maxv[o].l = maxv[o].r = l;
sum[o] = pre[o] = last[o] = maxv[o];
return ;
}
build(l, m, o<<1);
build(m+1, r, o<<1|1);
push_up(l, r, o);
}
node querysum(int L, int R, int l, int r, int o) {
if(L <= l && r <= R) return sum[o];

int m = (l + r) >> 1;
int inf = 1e9 + 7;
node ans = node(0, inf, -inf);
if(L <= m) {
ans = querysum(L, R, l, m, o<<1);
}
if(m < R) {
node cur = querysum(L, R, m+1, r, o<<1|1);
ans = node(ans.v+cur.v, min(ans.l,cur.l), max(ans.r,cur.r));
}
return ans;
}
node querypre(int L, int R, int l, int r, int o) {
int m = (l + r) >> 1;
if(L <= l && r <= R) return pre[o];
node ans = node(-INF, 0, 0);
if(m >= R) return querypre(L, R, l, m, o<<1);
if(L > m) return querypre(L, R, m+1, r, o<<1|1);
if(m >= L && m+1 <= R) {
node cur1 = querypre(L, R, l, m, o<<1);
node cur2 = querypre(L, R, m+1, r, o<<1|1);
ans = cur1;
node sum1 = querysum(L, R, l, m, o<<1);
node hehe = node(sum1.v+cur2.v, sum1.l, cur2.r);
if(ans.v < hehe.v) ans = hehe;
else if(ans.v == hehe.v) {
if(ans.l > hehe.l) ans = hehe;
else if(ans.l == hehe.l) {
if(ans.r > hehe.r) ans = hehe;
}
}
}
return ans;
}
node querylast(int L, int R, int l, int r, int o) {
int m = (l + r) >> 1;
if(L <= l && r <= R) return last[o];
node ans = node(-INF, 0, 0);
if(m >= R) return querylast(L, R, l, m, o<<1);
if(L > m) return querylast(L, R, m+1, r, o<<1|1);
if(m >= L && m+1 <= R) {
node cur1 = querylast(L, R, l, m, o<<1);
node cur2 = querylast(L, R, m+1, r, o<<1|1);
ans = cur2;
node sum2 = querysum(L, R, m+1, r, o<<1|1);
node hehe = node(sum2.v+cur1.v, cur1.l, sum2.r);
if(ans.v < hehe.v) ans = hehe;
else if(ans.v == hehe.v) {
if(ans.l > hehe.l) ans = hehe;
else if(ans.l == hehe.l) {
if(ans.r > hehe.r) ans = hehe;
}
}
}
return ans;
}
node query(int L, int R, int l, int r, int o) {
int m = (l + r) >> 1;
if(L <= l && r <= R) return maxv[o];
node ans = node(-INF, 0, 0);
if(m >= R) return query(L, R, l, m, o<<1);
if(L > m) return query(L, R, m+1, r, o<<1|1);
if(m >= L && m+1 <= R) {
node cur1 = query(L, R, l, m, o<<1);
node cur2 = query(L, R, m+1, r, o<<1|1);
ans = cur1;
if(ans.v < cur2.v) ans = cur2;
else if(ans.v == cur2.v) {
if(ans.l > cur2.l) ans = cur2;
else if(ans.l == cur2.l) {
if(ans.r > cur2.r) ans = cur2;
}
}
node last1 = querylast(L, R, l, m, o<<1);
node pre2 = querypre(L, R, m+1, r, o<<1|1);
node hehe = node(last1.v+pre2.v, last1.l, pre2.r);
if(ans.v < hehe.v) ans = hehe;
else if(ans.v == hehe.v) {
if(ans.l > hehe.l) ans = hehe;
else if(ans.l == hehe.l) {
if(ans.r > hehe.r) ans = hehe;
}
}
}
return ans;
}
int l, r, kase = 0;
int main() {
while(~scanf("%d%d",&n, &m)) {
build(1, n, 1);
printf("Case %d:\n", ++kase);
while(m--) {
scanf("%d%d", &l, &r);
node cur = query(l, r, 1, n, 1);
printf("%d %d\n", cur.l, cur.r);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm-icpc uva 数据结构