codevs3981动态最大子段和(线段树)
3981 动态最大子段和
题目还是简单一点好...
有n个数,a[1]到a[n]。
接下来q次查询,每次动态指定两个数l,r,求a[l]到a[r]的最大子段和。
子段的意思是连续非空区间。
第一行一个数n。
第二行n个数a[1]~a[n]。
第三行一个数q。
以下q行每行两个数l和r。
q行,每行一个数,表示a[l]到a[r]的最大子段和。
7
2 3 -233 233 -23 -2 233
4
1 7
5 6
2 5
2 3
441
-2
233
3
对于50%的数据,q*n<=10000000。
对于100%的数据,1<=n<=200000,1<=q<=200000。
a[1]~a[n]在int范围内,但是答案可能超出int范围。
数据保证1<=l<=r<=n。
空间128M,时间1s。
我不会告诉你数据里有样例
/*
线段树区间操作GSS
一段长的区间的 GSS 有三种情况:
1 完全在左子区间
2 完全在右子区间
3 横跨左右区间
前两种情况可使用子区间的 GSS,但如何处理第三种情况?
注意到我们可以把区间拆成两部分,这两部分是不相关的。
所以我们需要维护一个区间的“最大左子段和”和“最大右子段和”。
gss = MAX{l.gss,r.gss,l.rgss + r.lgss}
由 GSS 一直推下来,对于每个节点,我们一共需要设计4个状态。
1 GSS:最大子段和
2 LGSS:最大左子段和
3 RGSS:最大右子段和
4 SUM:整段和
这里我用了结构体存储(元元真厉害啊!)
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define maxn 2000010 using namespace std;
ll n,a[maxn],q,x,y,ans;
struct node{
ll l,r,dis,mx,lmx,rmx;
}tre[maxn>>]; ll init()
{
ll x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} void build(int now,ll l,ll r)
{
tre[now].l=l;tre[now].r=r;
if(l==r)
{
tre[now].dis=init();
tre[now].lmx=tre[now].rmx=tre[now].mx=tre[now].dis;
return ;
}
ll mid=(l+r)>>;
build(now<<,l,mid);
build(now<<|,mid+,r);
//下面是重点之一,要注意。
tre[now].lmx=max(tre[now<<].lmx,tre[now<<].dis+tre[now<<|].lmx);
tre[now].rmx=max(tre[now<<|].rmx,tre[now<<|].dis+tre[now<<].rmx);
tre[now].mx=max(tre[now<<].rmx+tre[now<<|].lmx,max(tre[now<<].mx,tre[now<<|].mx));
tre[now].dis=tre[now<<].dis+tre[now<<|].dis;
} node query(int now,ll l,ll r)
{
node ans;
if(l==tre[now].l&&r==tre[now].r) return tre[now];
ll mid=(tre[now].l+tre[now].r)>>;
if(l>mid) return query(now<<|,l,r);
else if(r<=mid) return query(now<<,l,r);
else//就是这里咋也不会写,递归找边界思路不清晰
{
node lch=query(now<<,l,mid);
node rch=query(now<<|,mid+,r);
ans.lmx=max(lch.lmx,lch.dis+rch.lmx);
ans.rmx=max(rch.rmx,rch.dis+lch.rmx);
ans.mx=max(max(lch.mx,rch.mx),lch.rmx+rch.lmx);
}
return ans;
}
int main()
{
n=init();
build(,,n);
q=init();
for(int i=;i<=q;i++)
{
x=init();y=init();
printf("%lld\n",query(,x,y).mx);
}
return ;
}
codevs3981动态最大子段和(线段树)的更多相关文章
- 【BZOJ3295】动态逆序对(线段树,树状数组)
[BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...
- 指针-动态开点&合并线段树
一个知识点不在一道题里说是没有灵魂的 线段树是用来处理区间信息的咯 但是往往因为需要4倍空间让许多人退却,而动态开点的线段树就非常棒 仿佛只用2倍就可以咯 指针保存位置,即节点信息,是很舒适的,所以用 ...
- BZOJ 4636 (动态开节点)线段树
思路: 偷懒 懒得离散化 搞了个动态开节点的线段树 (其实是一样的--..) 注意会有a=b的情况 要判掉 //By SiriusRen #include <cstdio> #includ ...
- zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap
Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...
- LA 3938 动态最大连续和 线段树
题目链接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show ...
- Luogu P4643 【模板】动态dp(矩阵乘法,线段树,树链剖分)
题面 给定一棵 \(n\) 个点的树,点带点权. 有 \(m\) 次操作,每次操作给定 \(x,y\) ,表示修改点 \(x\) 的权值为 \(y\) . 你需要在每次操作之后求出这棵树的最大权独立集 ...
- [BZOJ3638 && BZOJ3272]带修区间不相交最大K子段和(线段树模拟费用流)
https://www.cnblogs.com/DaD3zZ-Beyonder/p/5634149.html k可重区间集问题有两种建图方式,可能这一种才可以被线段树优化. 换个角度看,这也是一个类似 ...
- luoguU60884 【模板】动态点分治套线段树
题目连接:https://www.luogu.org/problemnew/show/U60884 题意:有N个点,标号为1∼N,用N−1条双向带权通道连接,保证任意两个点能互相到达. Q次询问,问从 ...
- AcWing1264. 动态求连续区间和 (线段树做法)
1.题目 给定 n 个数组成的一个数列,规定有两种操作,一是修改某个元素,二是求子数列 [a,b] 的连续和. 输入格式 第一行包含两个整数 n 和 m,分别表示数的个数和操作次数. 第二行包含 n ...
随机推荐
- code blocks 安装与实践
背景 因为不是主要修习C/C++,仅用于写算法和数据结构,code blocks轻量但是安装老是出现问题,故有此记录 安装 官方地址:http://www.codeblocks.org/downloa ...
- 洛谷——P2171 Hz吐泡泡
P2171 Hz吐泡泡 题目描述 这天,Hz大大心血来潮,吐了n个不同的泡泡玩(保证没有重复的泡泡).因为他还要写作业,所以他请你帮他把这些泡泡排序成树(左子树<=根<右子树).输出它的后 ...
- UVA - 11175 From D to E and Back(思路)
题目: 思路: 如图E:图中a.b.c.d是有向图D中的顶点,如果ac.bc都指向cd,而ac又指向ce,那bc同样应该有一条指向ce的边不然就不能从图D转换来.所以直接枚举顶点就可以了. 代码: # ...
- <SpringMvc>入门六 异常处理
如果不做异常处理,那么一直将错误向上抛出,则会最后在页面上显示错误代码 服务启动后,访问test1方法,页面会报500 为了提示友好的错误页面,所以需要做异常处理 1.编写自定义异常类(做提示信息的) ...
- Shell脚本中非交互式修改密码的方法(转)
这篇文章主要介绍了Shell脚本中非交互式修改密码的两种方法,本文讲解了使用chpasswd和使用passwd和--stdin组合两种方法,需要的朋友可以参考下. 对系统定期修改密码是一个很重要的安全 ...
- for 循环新的写法==列表解析
1. (for x in L1) 是一个可迭代对象: 2. 列表解析比for 循环快,列表解析的迭代在解释器内部是以C语言速度执行, 而不是手动python代码执行: (x+10 for x in L ...
- 洛谷 2777 [AHOI2016初中组]自行车比赛
[题解] 为了让某个选手能够获得总分第一,就让他最后一天的得分是n,并且让别的选手的得分的最大值尽量小.于是我们先把目前积分排序,并且让他们最后一天的排名刚好与积分排名相反.即某个积分排名为X的人最后 ...
- noip模拟赛 罪犯分组
分析:看了题后没别的思路,感觉就是dp,普通dp的话状态和方程实在是不好设计,观察数据,发现N非常小,暗示了这道题要用状压dp来做. 先枚举每个集合,再用O(n^2)的暴力看这个集合内有多少个冲突,如 ...
- 使用Vundle管理配置Vim的插件
1.介绍: 安装需要Git,触发git clone,默认将每一个指定特定格式插件的仓库复制到~/.vim/bundle/. 搜索需要Curl支持. Windows用户请直接访问Windows setu ...
- Oracle Multitenant Environment (三) Plan for a cdb
Below tables contains contant you need to consider while planning for a CDB. Action Considerations f ...