线段树(区间合并) LA 3989 "Ray, Pass me the dishes!"
题意:动态最大连续子序列和,静态的题目
分析:nlogn的归并思想。线段树维护结点的三个信息,最大前缀和,最大后缀和,该区间的最大和的两个端点,然后答案是三个的better。书上用pair保存端点,用自带的<来得到最优。
#include <bits/stdc++.h>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
typedef pair<int, int> P;
const int N = 5e5 + 5;
ll sum[N];
struct ST {
int pre[N<<2], suf[N<<2];
P sub[N<<2];
ll get_sum(P p) {
return sum[p.second] - sum[p.first-1];
}
P better(P a, P b) {
ll v1 = get_sum (a), v2 = get_sum (b);
if (v1 != v2) return v1 > v2 ? a : b;
else return a < b ? a : b;
}
void push_up(int l, int r, int rt) {
pre[rt] = better (make_pair (l, pre[rt<<1]), make_pair (l, pre[rt<<1|1])).second; //该区间的最大前缀
suf[rt] = better (make_pair (suf[rt<<1], r), make_pair (suf[rt<<1|1], r)).first; //该区间的最大后缀
sub[rt] = better (sub[rt<<1], sub[rt<<1|1]); //该区间的最大连续和:max (左前缀,右后缀+左前缀,右后缀)
sub[rt] = better (sub[rt], make_pair (suf[rt<<1], pre[rt<<1|1])); //不一定就是最大前缀或最大后缀
}
void build(int l, int r, int rt) {
if (l == r) {
pre[rt] = suf[rt] = l;
sub[rt] = make_pair (l, l);
return ;
}
int mid = (l + r) >> 1;
build (lson); build (rson);
push_up (l, r, rt);
}
P query_pre(int ql, int qr, int l, int r, int rt) {
if (pre[rt] <= qr) return make_pair (l, pre[rt]);
int mid = (l + r) >> 1;
if (qr <= mid) return query_pre (ql, qr, lson);
P p = query_pre (ql, qr, rson); p.first = l;
return better (p, make_pair (l, pre[rt<<1]));
}
P query_suf(int ql, int qr, int l, int r, int rt) {
if (suf[rt] >= ql) return make_pair (suf[rt], r);
int mid = (l + r) >> 1;
if (ql > mid) return query_suf (ql, qr, rson);
P p = query_suf (ql, qr, lson); p.second = r;
return better (p, make_pair (suf[rt<<1|1], r));
}
P query(int ql, int qr, int l, int r, int rt) {
if (ql <= l && r <= qr) return sub[rt];
int mid = (l + r) >> 1;
if (qr <= mid) return query (ql, qr, lson);
if (ql > mid) return query (ql, qr, rson);
P p1 = query_suf (ql, qr, lson); //ql <= mid < qr
P p2 = query_pre (ql, qr, rson); //和push_up一样
P p3 = better (query (ql, qr, lson), query (ql, qr, rson)); //该区间的最大连续和:max (左前缀,右后缀+左前缀,右后缀)
return better (p3, make_pair (p1.first, p2.second));
}
}st; int main(void) {
int n, q, cas = 0;
while (scanf ("%d%d", &n, &q) == 2) {
for (int i=1; i<=n; ++i) {
scanf ("%lld", &sum[i]); sum[i] += sum[i-1];
}
st.build (1, n, 1);
printf ("Case %d:\n", ++cas);
int ql, qr;
while (q--) {
scanf ("%d%d", &ql, &qr);
P ans = st.query (ql, qr, 1, n, 1);
printf ("%d %d\n", ans.first, ans.second);
}
} return 0;
}
线段树(区间合并) LA 3989 "Ray, Pass me the dishes!"的更多相关文章
- UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)
"Ray, Pass me the dishes!" UVA - 1400 题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点.要求字典序最小 ...
- SPOJ GSS1_Can you answer these queries I(线段树区间合并)
SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- HYSBZ 1858 线段树 区间合并
//Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...
- poj3667 线段树 区间合并
//Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- hdu3911 线段树 区间合并
//Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- 线段树(区间合并) POJ 3667 Hotel
题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...
随机推荐
- Google 如何修复 TrustManager 实施方式不安全的应用
引用谷歌市场的帮助说明:https://support.google.com/faqs/answer/6346016 本文面向的是发布的应用中 X509TrustManager 接口实施方式不安全的开 ...
- Java返回距离当前时间段
/** * 计算该时间离当前时间的差距 * @param time 格式为:yyyy-MM-dd HH:mm:ss * @return */ public static String getShort ...
- 51nod1019逆序数(归并排序/树状数组)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1019 题意:中文题诶- 思路: 方法1:归并排序- 归并排序过 ...
- Android Matrix
转自 :http://www.cnblogs.com/qiengo/archive/2012/06/30/2570874.html#code Matrix的数学原理 平移变换 旋转变换 缩放变换 错切 ...
- How many Fibs?【sudt 2321】【大数的加法及其比较】
How many Fibs? Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 Recall the definition of t ...
- css 妙味 总结
技巧一: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF- ...
- 腾讯微博的账号登录及api操作
.tqq.php <?php /** * PHP Library for t.qq.com * * @author */ class tqqPHP { function __construct( ...
- 使用Visual Studio Code开发AngularJS应用
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:VSC发布之后,尤其最近刚刚更新到0.3之后,社区出现了很多介绍VSC使用的好文章.比 ...
- JSP/Servlet的编码原理
转自:http://janwer.iteye.com/blog/150226 首先,说说 JSP/Servlet 中的几个编码的作用 在 JSP/Servlet 中主要有以下几种设置编码的方式: pa ...
- Centos7-mqtt消息中间件mosquitto的安装和配置
在以前发布的博客"菜鸟是如何打造智能家居系统的"文章最后我提到了使用MQTT协议作为云平台和设备之间的通信协议以达到消息传递的实时性,手机的消息推送也大多基于这种平台,首先搬来一段 ...