线段树(区间合并) 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[]统计从左端点起最长连续空房间 ...
随机推荐
- IOS-在ARC项目中使用非ARC框架或者类库
1.在ARC项目中使用非ARC框架或者类库 IOS 4引入了Automatic Reference Count(ARC),编译器可以在编译时对obj-c对象进行内存管理. 之前,obj-c的内存管理方 ...
- 如何给DropDownList在后台代码中添加一个空的选项
代码如何: ddl_dept.Items.Insert(, new ListItem("---请选择---","")); new ListItem的第一个参数表 ...
- NYOJ之奇偶数分离
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAscAAAJ8CAIAAACdmZvPAAAgAElEQVR4nO3dPVLjStsG4G8T5CyEFC
- profiler加入计划任务
创建profiler的存储过程: USE [xxxDB] GO /****** Object: StoredProcedure [dbo].[CreateProfile] Script Date: 2 ...
- Clr Via C#读书笔记---计算限制的异步操作
线程池基础 1,线程的创建和销毁是一个昂贵的操作,线程调度以及上下文切换耗费时间和内存资源. 2,线程池是一个线程集合,供应你的用程序使用. 3,每个CLR有一个自己的线程池,线程池由CLR控制的所有 ...
- Ext Js【Hello World】 ——4.1 beta 1
准备:vs+ExtJs4.1Beta1 ExtJS 4.1 xiazai_ https://yunpan.cn/cqv6bdBwtRjAj (提取码:2733) 引用,cs文件,js主入口,zh—c ...
- MySql中delimiter的作用是什么?
这个命令与存储过程没什么关系吧.其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了.默认情况下,delimiter是分号;.在命令行客户端中,如果有一行命令以分号结束,那么 ...
- jQuery发送ajax请求
利用jquery发送ajax请求的几个模板代码. $.ajax({ async : false, type: 'POST', dataType : "json", url: &qu ...
- 攻城狮在路上(叁)Linux(二十四)--- linux设置开机挂载及镜像文件挂载
虽然可以手动进行文件系统的挂载,但是每次都手动挂载就会很麻烦,开机挂载的目的就是实现文件系统的自动挂载. 一.开机挂载:/etc/fstab及/etc/mtab 主要是通过修改/etc/fstab文件 ...
- 验证备份前设置CONFIGURE CONTROLFILE AUTOBACKUP ON/OFF; 的区别
关于rman的,环境: oracle 10.2.0 rman nocatalog方式 1.首先设置 CONFIGURE CONTROLFILE AUTOBACKUP ON; 然后进行数据库全备份 RM ...