UVA - 1400"Ray, Pass me the dishes!"(线段树)
来源:互联网 发布:网上淘宝客服兼职 编辑:程序博客网 时间:2024/05/16 09:24
UVA - 1400"Ray, Pass me the dishes!"(线段树)
题目链接
题目大意:给你N个数字,要求你动态的给出L到R之间,X>= L && Y<=R,使得X,Y这段的连续和是LR之间的最大连续和,如果有多解,输出X小的,接着是Y小的。
解题思路:结点保存三个附加线段,max_sub, max_suffix, max_prefix.对于每次查询最大的连续和要不出现在左子树的max_sub, 要不就是右子树的max_sub, 要不就是左子树的max_suffix + 右子树的max_prefix.然后每次查询的时候都返回一个新的节点,是新的控制范围和在这个范围内的对应的三个线段值。求max_prefix和max_suffix的时候要注意。
代码:
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int N = 5e5 + 5;#define lson(x) ((x)<<1)#define rson(x) (((x)<<1) + 1)ll A[N], S[N];struct Segment { ll v; int l, r; Segment(int l = 0, int r = 0, ll v = 0) { this->l = l; this->r = r; this->v = v; } Segment operator + (const Segment& a) const{ Segment ans; ans.l = min (l, a.l); ans.r = max (r, a.r); ans.v = v + a.v; return ans; } bool operator < (const Segment &a) const { if (v == a.v) { if (l == a.l) return r > a.r; return l > a.l; } return v < a.v; }};struct Node { int l, r; Segment max_sub, max_prefix, max_suffix; void set (int l, int r, Segment max_sub, Segment max_prefix, Segment max_suffix) { this->l = l; this->r = r; this->max_sub = max_sub; this->max_prefix = max_prefix; this->max_suffix = max_suffix; }}node[4 * N];Node Seg_merge(Node a, Node b) { Node ret; ll suml = S[a.r] - S[a.l - 1]; ll sumr = S[b.r] - S[b.l - 1]; ret.l = a.l; ret.r = b.r; ret.max_sub = max(a.max_suffix + b.max_prefix, max(a.max_sub, b.max_sub)); ret.max_prefix = max (a.max_prefix, Segment(a.l, a.r, suml) + b.max_prefix); ret.max_suffix = max (b.max_suffix, a.max_suffix + Segment(b.l, b.r, sumr)); return ret;}void build (int u, int l, int r) { if (l == r) { Segment max_sub(l, r, A[l]); Segment max_prefix(l, r, A[l]); Segment max_suffix(l, r, A[l]); node[u].set(l, r, max_sub, max_prefix, max_suffix); } else { int m = (l + r) / 2; build(lson(u), l, m); build(rson(u), m + 1, r); node[u] = Seg_merge(node[lson(u)], node[rson(u)]); } }Node Query (int u, int ql, int qr) { if (ql <= node[u].l && qr >= node[u].r) return node[u]; int m = (node[u].l + node[u].r) / 2; if (ql > m) return Query (rson(u), ql, qr); else if (qr <= m) return Query (lson(u), ql, qr); else return Seg_merge(Query(lson(u), ql, qr), Query(rson(u), ql, qr));}int n, m;int main () { int cas = 0; int l, r; Node ans; while (scanf ("%d%d", &n, &m) != EOF) { S[0] = 0; for (int i = 1; i <= n; i++) { scanf ("%lld", &A[i]); S[i] = S[i - 1] + A[i]; } printf ("Case %d:\n", ++cas); build(1, 1, n); for (int i = 0; i < m; i++) { scanf ("%d%d", &l, &r); ans = Query(1, l, r); printf ("%d %d\n", ans.max_sub.l, ans.max_sub.r); } } return 0;}
0 0
- UVA 1400 1400 - "Ray, Pass me the dishes!"(线段树)
- uva 1400 "Ray, Pass me the dishes!" 线段树
- uva 1400 - "Ray, Pass me the dishes!"(线段树)
- UVA - 1400"Ray, Pass me the dishes!"(线段树)
- UVA 1400 "Ray, Pass me the dishes!" (线段树)
- UVa 1400 "Ray, Pass me the dishes!"(线段树)
- UVA 1400 "Ray, Pass me the dishes!"(线段树)
- UVa Ray, Pass me the dishes! (线段树)
- UVa-1400 - "Ray, Pass me the dishes!"
- uva 1400 "Ray, Pass me the dishes!"
- UVA 1400 Ray, Pass me the dishes!
- 线段树(1):点修改 (uva 1400 Ray,Pass me the Dishes)
- UVA-1400 Ray, Pass me the Dishes, LA 3938 , 线段树,区间查询
- Uva 1400 "Ray, Pass me the dishes!" (线段树 区间合并)
- uva 1400 Ray, Pass me the dishes!(线段树, 分治法求最大连续和)
- UVa 1400 Ray, Pass me the dishes!(线段树:复杂段查询)
- UVa 3938 "Ray, Pass me the dishes!"
- LA 3938 - "Ray, Pass me the dishes!"(线段树)
- 串操作指令
- 孙红雷携女友珠宝店挑大钻戒 获VIP专属服务
- 最美学生会主席完爆北大小师妹 艺术生面孔学霸心K掉古装秀
- 过滤sd卡中隐藏的文件
- 白话压缩感知(含Matlab代码)
- UVA - 1400"Ray, Pass me the dishes!"(线段树)
- hdu 2254 奥运[有向图从v1到v2方案数](大坑)
- OpenCV基础篇之绘图及RNG随机数对象
- 关于使用DFRobot的Mini MP3 Player的串口指令
- linux I2C读写实例 .
- 阿萨德可京爱了似的了金卡路上看见的了看见阿里是科技大
- Jtable导入excel
- OpenCV基础篇之像素访问
- ResourceManager内部组成