线段树-区间合并uva1400(LA3938)
2014-02-20 21:38
288 查看
"Ray, Pass me the dishes!"
求最大连续和。
写起来太蛋疼了,还是因各种细节过不了,忘了考虑,多组满足时x尽量小,y尽量小,查询的时候也是缺这个少那个。。。
下面是标程,写的很漂亮,多学习!
求最大连续和。
写起来太蛋疼了,还是因各种细节过不了,忘了考虑,多组满足时x尽量小,y尽量小,查询的时候也是缺这个少那个。。。
下面是标程,写的很漂亮,多学习!
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 500000 + 10; const int maxnode = 1000000 + 10; typedef long long LL; typedef pair<int,int> Interval; LL prefix_sum[maxn]; LL sum(int L, int R) { return prefix_sum[R] - prefix_sum[L-1]; } LL sum(Interval p) { return sum(p.first, p.second); } Interval better(Interval a, Interval b) { if(sum(a) != sum(b)) return sum(a) > sum(b) ? a : b; return a < b ? a : b; // 利用pair自带的字典序 } int qL, qR; struct IntervalTree { int max_prefix[maxnode]; int max_suffix[maxnode]; Interval max_sub[maxnode]; void build(int o, int L, int R) { if(L == R) { max_prefix[o] = max_suffix[o] = L; max_sub[o] = make_pair(L, L); } else { int M = L + (R-L)/2; // 递归创建子树 int lc = o*2, rc = o*2+1; build(lc, L, M); build(rc, M+1, R); // 递推max_prefix LL v1 = sum(L, max_prefix[lc]); LL v2 = sum(L, max_prefix[rc]); if(v1 == v2) max_prefix[o] = min(max_prefix[lc], max_prefix[rc]); else max_prefix[o] = v1 > v2 ? max_prefix[lc] : max_prefix[rc]; // 递推max_suffix v1 = sum(max_suffix[lc], R); v2 = sum(max_suffix[rc], R); if(v1 == v2) max_suffix[o] = min(max_suffix[lc], max_suffix[rc]); else max_suffix[o] = v1 > v2 ? max_suffix[lc] : max_suffix[rc]; // 递推max_sub max_sub[o] = better(max_sub[lc], max_sub[rc]); // 完全在左子树或者右子树 max_sub[o] = better(max_sub[o], make_pair(max_suffix[lc], max_prefix[rc])); // 跨越中线 } } Interval query_prefix(int o, int L, int R) { if(max_prefix[o] <= qR) return make_pair(L, max_prefix[o]); int M = L + (R-L)/2; int lc = o*2, rc = o*2+1; if(qR <= M) return query_prefix(lc, L, M); Interval i = query_prefix(rc, M+1, R); i.first = L; return better(i, make_pair(L, max_prefix[lc])); } Interval query_suffix(int o, int L, int R) { if(max_suffix[o] >= qL) return make_pair(max_suffix[o], R); int M = L + (R-L)/2; int lc = o*2, rc = o*2+1; if(qL > M) return query_suffix(rc, M+1, R); Interval i = query_suffix(lc, L, M); i.second = R; return better(i, make_pair(max_suffix[rc], R)); } Interval query(int o, int L, int R) { if(qL <= L && R <= qR) return max_sub[o]; int M = L + (R-L)/2; int lc = o*2, rc = o*2+1; if(qR <= M) return query(lc, L, M); if(qL > M) return query(rc, M+1, R); Interval i1 = query_prefix(rc, M+1, R); // 右半的前缀 Interval i2 = query_suffix(lc, L, M); // 左半的后缀 Interval i3 = better(query(lc, L, M), query(rc, M+1, R)); return better(make_pair(i2.first, i1.second), i3); } }; IntervalTree tree; int main() { int kase = 0, n, a, Q; while(scanf("%d%d", &n, &Q) == 2) { prefix_sum[0] = 0; for(int i = 0; i < n; i++) { scanf("%d", &a); prefix_sum[i+1] = prefix_sum[i] + a; } tree.build(1, 1, n); printf("Case %d:\n", ++kase); while(Q--) { int L, R; scanf("%d%d", &L, &R); qL = L; qR = R; Interval ans = tree.query(1, 1, n); printf("%d %d\n", ans.first, ans.second); } } return 0; }
相关文章推荐
- UVA 1400 "Ray, Pass methe dishes!"(线段树,区间合并)
- UVA-1400-"Ray, Pass me the dishes!"(线段树-区间合并)
- 线段树区间合并——UVA 1400
- Uva 1400 "Ray, Pass me the dishes!" (线段树 区间合并)
- LA3938 "Ray, Pass me the dishes!" (线段树区间合并)
- LA3938 & UVA1400 - Ray, Pass me the dishes!(线段树)
- UVA-11235-线段树加区间合并
- UVALive 3938 Ray, Pass me the dishes (线段树区间合并)
- UVA-1400 Ray, Pass me the Dishes, LA 3938 , 线段树,区间查询
- UVALive - 3938 Ray, Pass methe dishes!"(动态最大连续和子序列,线段树区间合并)
- uva1400 区间最大连续和 线段树
- POJ 3667 Hotel(线段树+区间合并+延迟标记)
- 线段树区间合并 hdu3308 LCIS
- POJ 3667 Hotel(线段树区间合并)
- HDU 1540 Tunnel Warfare(线段树区间合并)
- CodeForces 46D Parking Lot(线段树区间合并)
- POJ 2750 Potted Flower (线段树区间合并)
- uva 11992 Fast Matrix Operations (线段树区间更新)
- hdu 1806(线段树区间合并)
- UESTC 1061 秋实大哥与战争 线段树区间合并