题目传送门

题意:动态最大连续子序列和,静态的题目

分析: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!"的更多相关文章

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

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

  2. SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...

  3. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  4. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  5. HDU 3911 Black And White(线段树区间合并+lazy操作)

    开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...

  6. HYSBZ 1858 线段树 区间合并

    //Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...

  7. poj3667 线段树 区间合并

    //Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  8. hdu3911 线段树 区间合并

    //Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  9. 线段树(区间合并) POJ 3667 Hotel

    题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...

随机推荐

  1. Java IO流题库

    一.    填空题 Java IO流可以分为   节点流   和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行. 输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数 ...

  2. iOS中UITableView的一些设置

    不可滑动: ? 1 tableView.userInteractionEnabled = NO; 也可以在storyboard中的userInteractionEnable属性设置 显示导向箭头: ? ...

  3. NYOJ题目100 1的个数

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsMAAAIqCAIAAABOpdBfAAAgAElEQVR4nO3drXLbzP834P9JhOdAgn ...

  4. Linux下第一次使用MySQL数据库,设置密码

    在终端下输入:/etc/rc.d/init.d/mysqld status 查看MySQL状态,看看是否运行. 没有运行的话就输入:/etc/rc.d/init.d/mysqld start 这时,就 ...

  5. Android -- getQuantityString无效

    原文:http://www.xuebuyuan.com/1510993.html 原因:中文没有复数语法.

  6. ListView + PopupWindow实现滑动删除

    原文:ListView滑动删除 ,仿腾讯QQ(鸿洋_) 文章实现的功能是:在ListView的Item上从右向左滑时,出现删除按钮,点击删除按钮把Item删除. 看过文章后,感觉没有必要把dispat ...

  7. Asp.Net - 7.AJAX

    AJAX简介 没有AJAX会怎么样?普通的ASP.Net每次执行服务端方法的时候都要刷新当前页面,比如实现显示服务器的时间.每次都要刷新面的坏处:页面刷新打断用户操作.速度慢.增加服务器的流量压力.如 ...

  8. MVC – 4.mvc初体验(1)

    1.MVC请求模式   2.MVC简单请求流程图 展开 折叠     3.返回string的mvc方法 展开 折叠   4.加载视图的方法  

  9. jQuery积累

    一:Google的CDN(内容分发网络) <head> <script type="text/javascript" src="http://ajax. ...

  10. Java并发编程实现概览

    并发概览 >>同步 如何同步多个线程对共享资源的访问是多线程编程中最基本的问题之一.当多个线程并发访问共享数据时会出现数据处于计算中间状态或者不一致的问题,从而影响到程序的正确运行.我们通 ...