http://acm.uestc.edu.cn/#/problem/show/844

程序设计竞赛

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
Submit Status

“你动规无力,图论不稳,数据结构松散,贪心迟钝,没一样像样的,就你还想和我同台竞技,做你的美梦!今天这场比赛,就是要让你知道你是多么的无能!!”

不训练,无以为战。有n项能力是ACM竞赛要求的,训练则能提升,忽略则会荒废。

这m天,你能做到如何。

Input

第一行两个整数n,m,分别表示有n项能力要求,共有m天。

第二行n个整数,第i个整数ai表示第i项能力的数值。

接下来m行,每行开始先读入一个整数si,表明这是一次询问还是一次能力变化。

si=0,表明这是一次询问,然后读入两个整数li,ri,表示询问在[li,ri]区间中任选一段连续序列,这段序列中所有能力值之和最大能是多少。

si=1,表明这是一次能力变化,然后读入两个整数xi,wi,表示第xi项能力变为了wi。

1≤n,m≤100000,−10000≤ai≤10000,1≤li≤ri≤n,1≤xi≤n,−10000≤wi≤10000

Output

有多少询问就输出多少行,每行输出一个整数,作为对该询问的回答。

Sample input and output

Sample Input Sample Output
4 4
1 2 3 4
0 1 3
1 3 -3
0 2 4
0 3 3
6
4
-3

思路:

每个节点维护4个值:
summ:此区间内的最大连续和
sum_:该节点以下的节点值得总和
suml:此区间的从左端开始的最大连续和
sumr:此区间的从右端开始的最大连续和
合并区间时,该区间的最大连续和为:max(左子节点的最大连续和,右子节点的最大连续和,左子节点的最大右连续和+右子节点的最大左连续和)

查询时返回一个整节点。因为每次要查询左子节点和右子节点,并且要比较它们的右连续最大和和左连续最大和,所以需要返回整个节点以便求值。

代码:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; #define INF 0x7fffffff
const int N=;
int n,m,a[N];
struct node
{
int left,right;
int sum_,summ,suml,sumr;
}tree[*N]; void build(int id,int l,int r);//建一棵线段树
node query_sum(int id,int l,int r);//查询区间和
void update(int id,int pos,int val);//更新位置pos的值 int main()
{
//freopen("D:\\input.in","r",stdin);
//freopen("D:\\output.out","w",stdout);
int bo,t1,t2;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
build(,,n);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&bo,&t1,&t2);
if(bo)
update(,t1,t2);
else{
node tmp=query_sum(,t1,t2);
printf("%d\n",tmp.summ);
}
}
return ;
}
void build(int id,int l,int r)
{
tree[id].left=l;
tree[id].right=r;
if(l==r)
{
tree[id].sum_=a[l];
tree[id].summ=a[l];
tree[id].suml=a[l];
tree[id].sumr=a[l];
}
else
{
int mid=(l+r)/;
build(*id,l,mid);
build(*id+,mid+,r);
tree[id].sum_=tree[*id].sum_+tree[*id+].sum_;
tree[id].summ=max(max(tree[*id].summ,tree[*id+].summ),(tree[*id].sumr+tree[*id+].suml));
tree[id].suml=max(tree[*id].suml,tree[*id].sum_+tree[*id+].suml);
tree[id].sumr=max(tree[*id+].sumr,tree[*id].sumr+tree[*id+].sum_);
}
}
node query_sum(int id,int l,int r)
{
if(tree[id].left==l&&tree[id].right==r)
return tree[id];
else
{
node tmp,k1,k2;
int flag1=,flag2=;
int mid=(tree[id].left+tree[id].right)/;
if(r<=mid) return query_sum(*id,l,r);
if(l>mid) return query_sum(*id+,l,r);
if(l<=mid){
k1=query_sum(*id,l,mid);
flag1=;
}
if(r>mid){
k2=query_sum(*id+,mid+,r);
flag2=;
}
if(flag1&flag2){
tmp.sum_=k1.sum_+k2.sum_;
tmp.suml=max(k1.suml,k1.sum_+k2.suml);
tmp.sumr=max(k2.sumr,k1.sumr+k2.sum_);
tmp.summ=max(max(k1.summ,k2.summ),k1.sumr+k2.suml);
}else{
if(flag1) tmp=k1;
else tmp=k2;
}
return tmp;
}
}
void update(int id,int pos,int val)
{
if(tree[id].left==tree[id].right)
{
tree[id].sum_=val;
tree[id].summ=val;
tree[id].suml=val;
tree[id].sumr=val;
}
else
{
int mid=(tree[id].left+tree[id].right)/;
if(pos<=mid) update(*id,pos,val);
else update(*id+,pos,val);
tree[id].sum_=tree[*id].sum_+tree[*id+].sum_;
tree[id].summ=max(max(tree[*id].summ,tree[*id+].summ),(tree[*id].sumr+tree[*id+].suml));
tree[id].suml=max(tree[*id].suml,tree[*id].sum_+tree[*id+].suml);
tree[id].sumr=max(tree[*id+].sumr,tree[*id].sumr+tree[*id+].sum_);
}
}

cdoj844-程序设计竞赛 (线段树的区间最大连续和)【线段树】的更多相关文章

  1. 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...

  2. ZZNU-OJ-2098 : Drink coffee【线段树合并区间或者 差分 + 二分索引树】

    : Drink coffee 时间限制: Sec 内存限制: MiB 提交: 答案正确: 提交 状态 讨论区 题目描述 为了在上课时保持清醒,凯伦需要一些咖啡.咖啡爱好者凯伦想知道最佳的温度来冲煮完美 ...

  3. HDU 6464 免费送气球 【权值线段树】(广东工业大学第十四届程序设计竞赛)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6464 免费送气球 Time Limit: 2000/1000 MS (Java/Others)    M ...

  4. 2016中国大学生程序设计竞赛 - 网络选拔赛 C. Magic boy Bi Luo with his excited tree

    Magic boy Bi Luo with his excited tree Problem Description Bi Luo is a magic boy, he also has a migi ...

  5. 2016年湖南省第十二届大学生计算机程序设计竞赛---Parenthesis(线段树求区间最值)

    原题链接 http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1809 Description Bobo has a balanced parenthes ...

  6. HDU 6464.免费送气球-动态开点-权值线段树(序列中第first小至第second小的数值之和)(感觉就是只有一个状态的主席树) (“字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛)

    免费送气球 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  7. fzu 2105 Digits Count ( 线段树 ) from 第三届福建省大学生程序设计竞赛

    http://acm.fzu.edu.cn/problem.php?pid=2105 Problem Description Given N integers A={A[0],A[1],...,A[N ...

  8. 【线段树】hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 I. Minimum

    题意:给你一个序列(长度不超过2^17),支持两种操作:单点修改:询问区间中最小的ai*aj是多少(i可以等于j). 只需要线段树维护区间最小值和最大值,如果最小值大于等于0,那答案就是minv*mi ...

  9. 吉首大学2019年程序设计竞赛(重现赛)-K(线段树)

    题目链接:https://ac.nowcoder.com/acm/contest/992/K 题意:给一个大小为1e5的数组,由0 1组成,有两种操作,包括区间修改,将一段区间内的0换成1,1换成0; ...

随机推荐

  1. 2018-2019 网络对抗技术 20165226 Exp4:恶意代码分析

    2018-2019 网络对抗技术 20165226 Exp4:恶意代码分析 目录 一.实验内容说明及基础问题回答 二.实验过程 Task1 系统运行监控 结合windows计划任务与netstat命令 ...

  2. HDU 2548 A strange lift

    A strange lift Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  3. [转]IIS 允许/禁止 目录浏览

    <?xml version="1.0" encoding="utf-8"?> <configuration> <system.we ...

  4. vSphere client 登陆ESXI主机“您无权登录次服务器”

    vCenter安装在虚拟机上,安装好后想调整下内存,直接把虚拟机关闭了电源,突然一想服务器都被我关了,还拿什么修改内存,完蛋! 突然想起,在使用vCenter之前,都是用vsphere client ...

  5. [UE4]蓝图重构

    假设现在有一个蓝图类BP_GunRife(已经有其它很多类在使用这个类),现在要增加另外一把枪BP_BunLauncher. 可以新建一个父类BP_Gun,让BP_GunRife和BP_BunLaun ...

  6. 信息学奥赛(NOIP)初赛学习方法推荐

    首先声明:本帖针对初学者,本帖只是列出一个大概的框架,不属于自学方法,有条件有能力,请找一位好老师来教,多跟前辈交流经验.(否则多会出现事倍功半的悲剧!) 一.初赛内容 初赛偏重于基础知识. 1. 一 ...

  7. DOM事件机制(事件捕获和事件冒泡和事件委托)

    内容: 1.事件复习 2.事件冒泡与事件捕获 3.事件委托 1.事件复习 (1)事件 事件是用来处理响应的一个机制,这个响应可以来自于用户(点击, 鼠标移动, 滚动), 也可以来自于浏览器 下面的链接 ...

  8. jQuery实现todo及轮播图

    内容: 1.todo程序 2.轮播图 1.todo程序 需求: 实现一个todo程序,可以添加数据,可以删除数据,可以修改数据,可以查看所有数据 另外实现自己的一系列弹窗:用于提示用户的提示框.用于警 ...

  9. linux上安装vsftpd

    介绍:在前几篇博客中博主介绍了,怎么用java语言搭建一个简单的网站.如果有些小伙伴想把自己做的网站发布到服务器上让别人访问的话,不妨可以关注博主的博客,博客会在接下来的几篇博客中介绍怎么把一个网站发 ...

  10. OpenACC 绘制曼德勃罗集

    ▶ 书上第四章,用一系列步骤优化曼德勃罗集的计算过程. ● 代码 // constants.h ; ; ; ; const double xmin=-1.7; ; const double ymin= ...