UVA 1400 - "Ray, Pass me the dishes!"

option=com_onlinejudge&Itemid=8&page=show_problem&category=501&problem=4146&mosmsg=Submission+received+with+ID+13958986" target="_blank" style="">题目链接

题意:给定一个序列,每次询问一个[L,R]区间。求出这个区间的最大连续子序列和

思路:线段树,每一个节点维护3个值。最大连续子序列。最大连续前缀序列,最大连续后缀序列,那么每次pushup的时候,依据这3个序列去拼凑得到新的一个结点就可以

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; #define lson(x) ((x<<1) + 1)
#define rson(x) ((x<<1) + 2)
#define MP(a, b) make_pair(a, b) typedef long long ll;
typedef pair<int, int> Point; const int N = 500005; int n, m;
ll a[N], sum[N]; struct Node {
int l, r;
int prex, sufx;
Point sub;
} node[4 * N]; ll get(Point x) {
return sum[x.second] - sum[x.first - 1];
} bool Max(Point a, Point b) {
long long sa = get(a);
long long sb = get(b);
if (sa != sb) return sa > sb;
return a < b;
} Point Maxsub(Node a, Node b) {
Point ans;
if (Max(a.sub, b.sub)) ans = a.sub;
else ans = b.sub;
if (Max(MP(a.sufx, b.prex), ans)) ans = MP(a.sufx, b.prex);
return ans;
} int Maxpre(Node a, Node b) {
Point ans = MP(a.l, a.prex);
if (Max(MP(a.l, b.prex), ans)) ans = MP(a.l, b.prex);
return ans.second;
} int Maxsuf(Node a, Node b) {
Point ans = MP(b.sufx, b.r);
if (Max(MP(a.sufx, b.r), ans)) ans = MP(a.sufx, b.r);
return ans.first;
} Node pushup(Node a, Node b) {
Node ans;
ans.l = a.l; ans.r = b.r;
ans.sub = Maxsub(a, b);
ans.prex = Maxpre(a, b);
ans.sufx = Maxsuf(a, b);
return ans;
} void build(int l, int r, int x) {
if (l == r) {
node[x].l = l; node[x].r = r;
node[x].prex = node[x].sufx = l;
node[x].sub = MP(l, l);
return ;
}
int mid = (l + r) / 2;
build(l, mid, lson(x));
build(mid + 1, r, rson(x));
node[x] = pushup(node[lson(x)], node[rson(x)]);
} Node Query(int l, int r, int x) {
if (l <= node[x].l && r >= node[x].r)
return node[x];
int mid = (node[x].l + node[x].r) / 2;
Node ans;
if (l <= mid && r > mid)
ans = pushup(Query(l, r, lson(x)), Query(l, r, rson(x)));
else if (l <= mid) ans = Query(l, r, lson(x));
else if (r > mid) ans = Query(l, r, rson(x));
return ans;
} int main() {
int cas = 0;
while (~scanf("%d%d", &n, &m)) {
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
sum[i] = sum[i - 1] + a[i];
}
build(1, n, 0);
printf("Case %d:\n", ++cas);
int a, b;
while (m--) {
scanf("%d%d", &a, &b);
Node ans = Query(a, b, 0);
printf("%d %d\n", ans.sub.first, ans.sub.second);
}
}
return 0;
}

UVA 1400 1400 - &quot;Ray, Pass me the dishes!&quot;(线段树)的更多相关文章

  1. UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)

    "Ray, Pass me the dishes!" UVA - 1400 题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点.要求字典序最小 ...

  2. UVALive3938 &quot;Ray, Pass me the dishes!&quot; 线段树动态区间最大和

    AC得相当辛苦的一道题.似乎不难,可是须要想细致, 開始的时候的错误思路----是受之前做过的区间最长连续子串影响http://blog.csdn.net/u011026968/article/det ...

  3. UvaLA 3938 "Ray, Pass me the dishes!"

                            "Ray, Pass me the dishes!" Time Limit: 3000MS   Memory Limit: Unkn ...

  4. 【LA3938】"Ray, Pass me the dishes!"

    原题链接 Description After doing Ray a great favor to collect sticks for Ray, Poor Neal becomes very hun ...

  5. UVa 1400 (线段树) "Ray, Pass me the dishes!"

    求一个区间的最大连续子序列,基本想法就是分治,这段子序列可能在区间的左半边,也可能在区间的右半边,也有可能是横跨区间中点,这样就是左子区间的最大后缀加上右子区间的最大前缀之和. 线段树维护三个信息:区 ...

  6. uva 1400 - "Ray, Pass me the dishes!"

    又是一道线段树区间更新的题: #include<cstdio> #include<algorithm> #include<cstring> #define ll l ...

  7. uva 1400 "Ray, Pass me the dishes!" (区间合并 最大子段和+输出左右边界)

    题目链接:https://vjudge.net/problem/UVA-1400 题意:给一串序列,求最大子段,如果有多个,输出字典序最小的那个的左右端点 思路: 之前写过类似的,这个麻烦点需要输出左 ...

  8. 1400 - "Ray, Pass me the dishes!"

    哈哈,原来题意看错了,但有多个解的时候,输出起点靠前的,如果起点一样,则输出终点靠前的,修改后AC的代码如下: #include <cstdio> #include <iostrea ...

  9. 线段树(区间合并) LA 3989 "Ray, Pass me the dishes!"

    题目传送门 题意:动态最大连续子序列和,静态的题目 分析:nlogn的归并思想.线段树维护结点的三个信息,最大前缀和,最大后缀和,该区间的最大和的两个端点,然后答案是三个的better.书上用pair ...

随机推荐

  1. hdu5279 YJC plays Minecraft

    题目描述 题解: 岛屿之间的边砍/不砍情况有$2^n$种, 但是需要剪掉所有的岛上都首尾相连的情况. $dp$一下对于完全图没有限制($f$)/有限制($g$)的情况数. 方程:$$f[i]=\sum ...

  2. nginx代理yum

    适用场景:有多台服务器,但是只有1台服务器可以出公网,此时即可使用如下方式,进行yum代理,解决内网服务器不能yum的尴尬. 一.首先需要把/etc/yum.repos.d下的文件备份到bak,然后留 ...

  3. mac rar文件解压缩

    在下载文件时经常遇到RAR格式的压缩文件, 之前从APP Store下载了免费的解压软件, 但是总觉着不好用, 广告信息很多. 好用的软件都要花钱, 所以找到了命令行解决的办法. 步骤如下: 首先需要 ...

  4. Django:调用css、image、js

    1.在项目的manage.py同级目录创建static.templates 2.编辑settings.py,在最后加入 STATIC_URL = '/static/' HERE = os.path.d ...

  5. 基于selenium爬取拉勾网职位信息

    1.selenium Selenium 本是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.而这一特性为爬虫开发提供了一个选择及方向,由于其本身依赖 ...

  6. Linux mint xfce 19 使用记录

    创建系统快照 创建系统快照是 Linux Mint 19 的重要建议,可以使用与更新管理器捆绑的 Timeshift 应用程序轻松完成创建与恢复. 这个阶段很重要,万一出现令人遗憾的事件,比如安装破坏 ...

  7. [MVC]Ajax辅助方法

    在开始使用Ajax辅助方法前,必须在页面中载入jQuery以及jquery.unobtrusive-ajax.js文件才能正常执行. 为了让网站载入适当的JS函数库,必须先让Layout页面载入适当的 ...

  8. Leetcode 306.累加数

    累加数 累加数是一个字符串,组成它的数字可以形成累加序列. 一个有效的累加序列必须至少包含 3 个数.除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和. 给定一个只包含数字 '0'- ...

  9. msp430入门编程41

    msp430中C语言的软件工程--状态机建模

  10. T1365 浴火银河星际跳跃 codevs

    http://codevs.cn/problem/1365/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 小 K 又在玩浴 ...