SPOJ GSS 5. Can you answer these queries V
2012-11-22 14:26
453 查看
题意
和 GSS1 一样,还是一个长度为 n 的序列和 m 个 querry,只不过这次 querry 的格式是 x1 y1 x2 y2,求 max{ a[i]+a[i+1]+...+a[j] }, x1<=i<=y1 x2<=j<=y2做法分析
同 GSS1 一样,只不过查询的时候需分类讨论:1、y1<x2:那么 [y1, x2] 这一段的数必取,再选择性的加上 Lmax[x1, y1-1] Rmax[x2+1, y2] 即可
2、y1>=x2:把整个 i 和 j 的取值分为三类讨论:
(1)、x1<=i<=x2, x2<=j<=y2:val[x2]+Rmax[x1, x2-1]+Lmax[x2+1, y2]
(2)、x2<=i<=y1, y1<=j<=y2:val[y1]+Rmax[x1, y1-1]+Lmax[y1+1, y2]
(3)、x2<=i<=j<=y1:Max[x1, y1]
取三种情况中最大的即可
参考代码
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; const int N=10010; const int INT_INF=0x3fffffff; int val ; class seg_tree { private: struct data { int st, en, val, Max, Lmax, Rmax; } T[N<<2]; public: data update(data Lson, data Rson) { data fa; fa.Lmax=max(Lson.Lmax, Lson.val+Rson.Lmax); fa.Rmax=max(Rson.Rmax, Rson.val+Lson.Rmax); fa.Max=max(max(Lson.Max, Rson.Max), Lson.Rmax+Rson.Lmax); fa.val=Lson.val+Rson.val; return fa; } void build(int id, int st, int en) { T[id].st=st, T[id].en=en; if(st==en) { T[id].val=T[id].Max=T[id].Lmax=T[id].Rmax=val[st]; return; } int mid=(st+en)>>1; build(id<<1, st, mid), build(id<<1|1, mid+1, en); data now=update(T[id<<1], T[id<<1|1]); T[id].val=now.val, T[id].Max=now.Max, T[id].Lmax=now.Lmax, T[id].Rmax=now.Rmax; } data query(int id, int L, int R) { if(L<=T[id].st && T[id].en<=R) { return T[id]; } int mid=(T[id].st+T[id].en)>>1; if(R<=mid) return query(id<<1, L, R); else if(L>mid) return query(id<<1|1, L, R); else return update(query(id<<1, L, mid), query(id<<1|1, mid+1, R)); } } seg; int main() { int t; scanf("%d", &t); while(t--) { int n; scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d", &val[i]); seg.build(1, 1, n); int m; scanf("%d", &m); for(int i=1, x1, y1, x2, y2; i<=m; i++) { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); if(y1<x2) { int ans=seg.query(1, y1, x2).val; if(x1<=y1-1) ans+=max(0, seg.query(1, x1, y1-1).Rmax); if(x2+1<=y2) ans+=max(0, seg.query(1, x2+1, y2).Lmax); printf("%d\n", ans); } else { int ans1=val[x2]; if(x1<=x2-1) ans1+=max(0, seg.query(1, x1, x2-1).Rmax); if(x2+1<=y2) ans1+=max(0, seg.query(1, x2+1, y2).Lmax); int ans2=val[y1]; if(x1<=y1-1) ans2+=max(0, seg.query(1, x1, y1-1).Rmax); if(y1+1<=y2) ans2+=max(0, seg.query(1, y1+1, y2).Lmax); int ans3=seg.query(1, x2, y1).Max; printf("%d\n", max(ans1, max(ans2, ans3))); } } } return 0; }
相关文章推荐
- 【SPOJ - GSS2】Can you answer these queries II(线段树)
- SPOJ GSS1 Can you answer these queries I
- SPOJ GSS3 Can you answer these queries III (线段树)
- SPOJ 4487. Can you answer these queries VI(GSS6 Splay tree)
- SPOJ GSS 1. Can you answer these queries I
- SPOJ GSS3 Can you answer these queries III
- SPOJ GSS1 Can you answer these queries I (线段树求区间最大连续和)
- 数据结构(线段树):SPOJ GSS3 - Can you answer these queries III
- bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树
- SPOJ GSS1 Can you answer these queries I
- SPOJ GSS3 Can you answer these queries III(线段树)
- SPOJ 4487. Can you answer these queries VI(GSS6) splay
- 【SPOJ-GSS6】Can you answer these queries VI【Splay】
- GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树
- SPOJ GSS1 Can you answer these queries I
- [SPOJ1557][GSS2][线段树]Can you answer these queries II[好题]
- Splay树(插入、删除、区间最大字段和)—— SPOJ - GSS6 Can you answer these queries VI
- SPOJ 2713. Can you answer these queries IV(GSS4 线段树)
- spoj(GSS3) 1716 Can you answer these queries III(线段树求最大子段和)
- SPOJ GSS1 - Can you answer these queries I(线段树维护GSS)