UVALive 3938 Ray, Pass me the dishes (线段树区间合并)
来源:互联网 发布:google 高程提取软件 编辑:程序博客网 时间:2024/05/29 19:23
题意: 求q次询问的静态区间连续最大和起始位置和终止位置 输出字典序最小的解
分析: 很显然的区间合并的题目啦
常理就是维护pre, sub, suf 最大的 前缀和, 连续和, 后缀和 然后这个题还要记录解的位置所以还要区间总和sum
然后解的位置preR, subL, subR, sufL 然后更新就好了 自己注意下字典序就好了 建树和查询都类似
总结: 死守着HH线段树风格 导致代码丑的飞起 不会变通 以及思路清晰 抽象函数的重要性
反正呢 多刷题多总结吧 偶尔用用结构体的 还是对于某些题的解题代码减少不错的 比如说本题
优美版: 参考之后100行左右
//// Created by TaoSama on 2015-09-15// Copyright (c) 2015 TaoSama. All rights reserved.////#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << " "#define prln(x) cout << #x << " = " << x << endlconst int N = 5e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;typedef long long LL;int n, q;LL a[N];#define root 1, n, 1#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1typedef pair<int, int> Interval;struct Node { int l, r; int preR, sufL; Interval sub;} dat[N << 2];LL sum(Interval x) { return a[x.second] - a[x.first - 1];}Interval getMax(Interval x, Interval y) { LL sx = sum(x), sy = sum(y); if(sx != sy) return sx > sy ? x : y; return x < y ? x : y;}Node push_up(Node x, Node y) { Node ret; ret.l = x.l; ret.r = y.r; ret.preR = getMax(Interval(x.l, x.preR), Interval(x.l, y.preR)).second; ret.sufL = getMax(Interval(y.sufL, y.r), Interval(x.sufL, y.r)).first; ret.sub = getMax(Interval(x.sufL, y.preR), getMax(x.sub, y.sub)); return ret;}void build(int l, int r, int rt) { if(l == r) { dat[rt].l = dat[rt].r = l; dat[rt].preR = dat[rt].sufL = l; dat[rt].sub = Interval(l, l); return; } int m = l + r >> 1; build(lson); build(rson); dat[rt] = push_up(dat[rt << 1], dat[rt << 1 | 1]);}Node query(int L, int R, int rt) { if(L <= dat[rt].l && dat[rt].r <= R) return dat[rt]; int m = dat[rt].l + dat[rt].r >> 1; Node ret; if(L <= m && R > m) ret = push_up(query(L, R, rt << 1), query(L, R, rt << 1 | 1)); else if(L <= m) ret = query(L, R, rt << 1); else if(R > m) ret = query(L, R, rt << 1 | 1); return ret;}int main() {#ifdef LOCAL freopen("in.txt", "r", stdin);// freopen("out.txt","w",stdout);#endif ios_base::sync_with_stdio(0); int kase = 0; while(scanf("%d%d", &n, &q) == 2) { for(int i = 1; i <= n; ++i) { int x; scanf("%d", &x); a[i] = a[i - 1] + x; } build(root); printf("Case %d:\n", ++kase); while(q--) { int l, r; scanf("%d%d", &l, &r); Interval ans = query(l, r, 1).sub; printf("%d %d\n", ans.first, ans.second); } } return 0;}
我写的丑瞎了的版本: 200行左右
//// Created by TaoSama on 2015-09-15// Copyright (c) 2015 TaoSama. All rights reserved.////#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << " "#define prln(x) cout << #x << " = " << x << endlconst int N = 5e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;#define root 1, n, 1#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1typedef long long LL;LL sum[N << 2], pre[N << 2], sub[N << 2], suf[N << 2];int preR[N << 2], subL[N << 2], subR[N << 2], sufL[N << 2];void push_up(int rt) { int ls = rt << 1, rs = rt << 1 | 1; sum[rt] = sum[ls] + sum[rs]; LL Max, l, r; //prefix Max = pre[ls], r = preR[ls]; if(pre[ls] < sum[ls] + pre[rs]) { Max = sum[ls] + pre[rs]; r = preR[rs]; } pre[rt] = Max, preR[rt] = r; //suffix Max = suf[rs], l = sufL[rs]; if(suf[rs] <= sum[rs] + suf[ls]) { Max = sum[rs] + suf[ls]; l = sufL[ls]; } suf[rt] = Max, sufL[rt] = l; //sub Max = sub[ls], l = subL[ls], r = subR[ls]; if(Max < suf[ls] + pre[rs]) { Max = suf[ls] + pre[rs]; l = sufL[ls], r = preR[rs]; } if(Max < sub[rs]) { Max = sub[rs]; l = subL[rs], r = subR[rs]; } sub[rt] = Max, subL[rt] = l, subR[rt] = r;}void build(int l, int r, int rt) { if(l == r) { scanf("%lld", &sum[rt]); pre[rt] = sub[rt] = suf[rt] = sum[rt]; preR[rt] = subL[rt] = subR[rt] = sufL[rt] = l; return; } int m = l + r >> 1; build(lson); build(rson); push_up(rt);}struct Node { LL sum, pre, sub, suf; int preL, preR, subL, subR, sufL, sufR;};Node query(int L, int R, int l, int r, int rt) { if(L <= l && r <= R) { Node t; t.sum = sum[rt]; t.pre = pre[rt]; t.sub = sub[rt]; t.suf = suf[rt]; t.preL = l; t.preR = preR[rt]; t.subL = subL[rt]; t.subR = subR[rt]; t.sufL = sufL[rt]; t.sufR = r; return t; } int m = l + r >> 1, x = 0, y = 0; Node ll, rr, ret; if(L <= m) ll = query(L, R, lson), x = 1; if(R > m) rr = query(L, R, rson), y = 1; if(x && !y) ret = ll; else if(!x && y) ret = rr; else { ret.sum = ll.sum + rr.sum; //prefix ret.pre = ll.pre, ret.preL = ll.preL, ret.preR = ll.preR; if(ret.pre < ll.sum + rr.pre) { ret.pre = ll.sum + rr.pre; ret.preL = ll.preL; ret.preR = rr.preR; } //suffix ret.suf = rr.suf, ret.sufL = rr.sufL, ret.sufR = rr.sufR; if(ret.suf <= rr.sum + ll.suf) { ret.suf = rr.sum + ll.suf; ret.sufL = ll.sufL; ret.sufR = rr.sufR; } //sub ret.sub = ll.sub, ret.subL = ll.subL, ret.subR = ll.subR; if(ret.sub < ll.suf + rr.pre) { ret.sub = ll.suf + rr.pre; ret.subL = ll.sufL; ret.subR = rr.preR; } if(ret.sub < rr.sub) { ret.sub = rr.sub; ret.subL = rr.subL; ret.subR = rr.subR; } } return ret;}int n, q;int main() {#ifdef LOCAL freopen("in.txt", "r", stdin);// freopen("out.txt","w",stdout);#endif ios_base::sync_with_stdio(0); int kase = 0; while(scanf("%d%d", &n, &q) == 2) { build(root); printf("Case %d:\n", ++kase); while(q--) { int l, r; scanf("%d%d", &l, &r); Node ans = query(l, r, root); printf("%d %d\n", ans.subL, ans.subR); } } return 0;}
0 0
- UVALive 3938 Ray, Pass me the dishes (线段树区间合并)
- UVALive - 3938 "Ray, Pass me the dishes!" (线段树)
- uvalive 3938 Ray, Pass me the dishes!(线段树)
- LA3938 "Ray, Pass me the dishes!" (线段树区间合并)
- UVALive - 3938 "Ray, Pass me the dishes!" 线段树
- UVaLive 3938 "Ray, Pass me the dishes!" (线段树求动态最大连续和)
- UVALive 3938 "Ray, Pass me the dishes!"
- UVALive - 3938 "Ray, Pass me the dishes!"
- UVALive 3938 "Ray, Pass me the dishes!"
- Uva 1400 "Ray, Pass me the dishes!" (线段树 区间合并)
- uvalive 3938 - "Ray, Pass me the dishes!" +动态最大连续和+线段树
- UVAlive - 3938 —— Ray, Pass me the dishes! 【线段树】
- LA 3938 - "Ray, Pass me the dishes!"(线段树)
- UVA-1400 Ray, Pass me the Dishes, LA 3938 , 线段树,区间查询
- UVa Ray, Pass me the dishes! (线段树)
- UVA 1400 "Ray, Pass me the dishes!" (线段树)
- [线段树点修改]动态最大连续和(Ray,Pass me the Dishes, LA 3938)
- UVA live 3938 - "Ray, Pass me the dishes!"(线段树)
- 安卓中Bitmap的处理
- 【剑指Offer】跳台阶
- Opencv图像线性滤波-滚动条
- android 状态栏一体化实现
- Cocos2d-x开发系列 创建C++工程、项目架构、设计模式的选择、适配策略、高清标清处理
- UVALive 3938 Ray, Pass me the dishes (线段树区间合并)
- 链表的实现
- 互联网产品设计
- 在版本低于android21下使用material progressbar风格的进度条
- 使用ios的成员函数进行格式化输入和输出
- 笔记
- 【剑指Offer】变态跳台阶
- 接口和抽象类的差别
- java面试题一 静态变量