题目链接:

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1939

来自:刘汝佳大白书P201.

解题思路:

构造一棵线段树,其中每个结点维护三个值,记录最大前缀和,最大后缀和最大连续和。

最大连续和要么完全在左段,要么完全在右段,要么在跨越中线。就是会是左段的最大后缀和+右段的最大前缀和。。。。

代码也是刘汝佳写的哦

代码:

 // LA3938 Ray, Pass me the dishes!
// Rujia Liu
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int maxn = + ;
const int maxnode = + ;
typedef long long LL;
typedef pair<int,int> Interval; LL prefix_sum[maxn]; LL sum(int L, int R)
{
return prefix_sum[R] - prefix_sum[L-];
} LL sum(Interval p)
{
return sum(p.first, p.second);
} Interval better(Interval a, Interval b)
{
if(sum(a) != sum(b)) return sum(a) > sum(b) ? a : b;
return a < b ? a : b; // 利用pair自带的字典序
} int qL, qR; struct IntervalTree
{
int max_prefix[maxnode];
int max_suffix[maxnode];
Interval max_sub[maxnode]; void build(int o, int L, int R)
{
if(L == R)
{
max_prefix[o] = max_suffix[o] = L;
max_sub[o] = make_pair(L, L);
}
else
{
int M = L + (R-L)/;
// 递归创建子树
int lc = o*, rc = o*+;
build(lc, L, M);
build(rc, M+, R); // 递推max_prefix
LL v1 = sum(L, max_prefix[lc]);
LL v2 = sum(L, max_prefix[rc]);
if(v1 == v2) max_prefix[o] = min(max_prefix[lc], max_prefix[rc]);
else max_prefix[o] = v1 > v2 ? max_prefix[lc] : max_prefix[rc]; // 递推max_suffix
v1 = sum(max_suffix[lc], R);
v2 = sum(max_suffix[rc], R);
if(v1 == v2) max_suffix[o] = min(max_suffix[lc], max_suffix[rc]);
else max_suffix[o] = v1 > v2 ? max_suffix[lc] : max_suffix[rc]; // 递推max_sub
max_sub[o] = better(max_sub[lc], max_sub[rc]); // 完全在左子树或者右子树
max_sub[o] = better(max_sub[o], make_pair(max_suffix[lc], max_prefix[rc])); // 跨越中线
}
} Interval query_prefix(int o, int L, int R)
{
if(max_prefix[o] <= qR) return make_pair(L, max_prefix[o]);
int M = L + (R-L)/;
int lc = o*, rc = o*+;
if(qR <= M) return query_prefix(lc, L, M);
Interval i = query_prefix(rc, M+, R);
i.first = L;
return better(i, make_pair(L, max_prefix[lc]));
} Interval query_suffix(int o, int L, int R)
{
if(max_suffix[o] >= qL) return make_pair(max_suffix[o], R);
int M = L + (R-L)/;
int lc = o*, rc = o*+;
if(qL > M) return query_suffix(rc, M+, R);
Interval i = query_suffix(lc, L, M);
i.second = R;
return better(i, make_pair(max_suffix[rc], R));
} Interval query(int o, int L, int R)
{
if(qL <= L && R <= qR) return max_sub[o];
int M = L + (R-L)/;
int lc = o*, rc = o*+;
if(qR <= M) return query(lc, L, M);
if(qL > M) return query(rc, M+, R);
Interval i1 = query_prefix(rc, M+, R); // 右半的前缀
Interval i2 = query_suffix(lc, L, M); // 左半的后缀
Interval i3 = better(query(lc, L, M), query(rc, M+, R));
return better(make_pair(i2.first, i1.second), i3);
}
}; IntervalTree tree; int main()
{
int kase = , n, a, Q;
while(scanf("%d%d", &n, &Q) == )
{
prefix_sum[] = ;
for(int i = ; i < n; i++)
{
scanf("%d", &a);
prefix_sum[i+] = prefix_sum[i] + a;
}
tree.build(, , n);
printf("Case %d:\n", ++kase);
while(Q--)
{
int L, R;
scanf("%d%d", &L, &R);
qL = L;
qR = R;
Interval ans = tree.query(, , n);
printf("%d %d\n", ans.first, ans.second);
}
}
return ;
}

LA 3938 动态最大连续和 线段树的更多相关文章

  1. LA 3938 动态最大连续和(线段树)

    https://vjudge.net/problem/UVALive-3938 题意:给出一个长度为n的整数序列D,你的任务是对m个询问作出回答.对于询问(a,b),需要找到两个下标x和y,使得a≤x ...

  2. LA 3938 动态最大连续和

    题目链接:https://vjudge.net/contest/146667#problem/C 题意:动态的求一个区间的最大连续和. 分析: 看上去可以RMQ去做,但是,当分成两个部分,原来的部分的 ...

  3. 【BZOJ3295】动态逆序对(线段树,树状数组)

    [BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...

  4. 指针-动态开点&合并线段树

    一个知识点不在一道题里说是没有灵魂的 线段树是用来处理区间信息的咯 但是往往因为需要4倍空间让许多人退却,而动态开点的线段树就非常棒 仿佛只用2倍就可以咯 指针保存位置,即节点信息,是很舒适的,所以用 ...

  5. BZOJ 4636 (动态开节点)线段树

    思路: 偷懒 懒得离散化 搞了个动态开节点的线段树 (其实是一样的--..) 注意会有a=b的情况 要判掉 //By SiriusRen #include <cstdio> #includ ...

  6. 【最长连续零 线段树】bzoj1593: [Usaco2008 Feb]Hotel 旅馆

    最长连续零的线段树解法 Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负 责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大 ...

  7. zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap

    Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...

  8. UVA_12697 满足条件的最短连续和 线段树维护

    好印象深刻的题,前天选拔赛给跪了.怪我这种关键题没敲出来. 题意很简单,给你一串无规则的数列,再给个m值,求出满足 数列和>=m的长度最小的连续子串...确实一开始卡住了,因为看数据肯定是nlo ...

  9. AcWing1264. 动态求连续区间和 (线段树做法)

    1.题目 给定 n 个数组成的一个数列,规定有两种操作,一是修改某个元素,二是求子数列 [a,b] 的连续和. 输入格式 第一行包含两个整数 n 和 m,分别表示数的个数和操作次数. 第二行包含 n ...

随机推荐

  1. MySQL 5.6 双机热备

    目录: 1.说明 2.数据手工同步 3.修改主数据库配置文件 4.修改从数据库配置文件 5.主数据库添加备份用户 6.从数据库设置为Slave 7.验证 1.说明   1)数据库版本要高于5.1 2) ...

  2. 《BI那点儿事》数据流转换——导入列、导出列

    导入列: 导入列例子现在来做一个例子:创建路径D:\Pictures随便在路径D:\Pictures中粘贴4个比较小的图像文件命名为01.png.02.png.03.png.04.png在路径D:\P ...

  3. 【java基础】方法2

    让形参可变的方法 jdk1.5之后,java允许定义形参长度可变的参数,允许为方法指定数量不确定的形参. package object; public class VariableParam { // ...

  4. mybatis-config.xml简单笔记

    mybatis-config.xml简单笔记 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ...

  5. SQL Server如何删除多余tempDB文件

    某时,创建了多个tempDB文件,已经超过了服务器核心数,现象删除tempDB文件,使其保持与CPU核心数相同.但是在删除的时候,发现无法删除,报出错误:无法删除文件“tempdev3”,因为它不能为 ...

  6. css 浮动

    1. 浮动 浮动是css的布局功能,在CSS中,包括div在内的任何元素都可以浮动的方式显示.它能够改变页面中对象的前后流动顺序.浮动元素会脱离文档流,不占据空间.浮动元素可以左右移动,直到碰到包含它 ...

  7. C++获取鼠标位置及全局检测鼠标行为

    1.获取鼠标位置(在屏幕的位置)  CPoint m_mouse; GetCursorPos(&m_mouse); 2. 屏幕转化为客户端(控件的相对位置)& 客户端位置转化为屏幕位置 ...

  8. python中元组(tuple)的用法

    t=(1,2,3) t=() t=(1,)#元组中只有一个值,需在值后面加上,不然会当int型识别 te.count(1) te.index(2) te[::-1]#关于切片跟列表一样的 tuple的 ...

  9. ITPUB网站的知识索引汇总

    1. ITPUB知识索引树 http://www.itpub.net/tree/ http://www.itpub.net/pubtree/index.htm 2. ITPUB知识索引贴——全文索引 ...

  10. 联机事务处理OLTP(on-line transaction processing)和联机分析处理OLAP(On-Line Analytical Processing)

         什么是OLAP(联机分析处理)?      这个是和数据处理非常相关的一个概念.接触过BI(商务智能)的同学一定清楚. 数据处理大致可以分成两大类:联机事务处理OLTP(on-line tr ...