加帕里公园的friends

Time Limit: 3000/1000MS (Java/Others) Memory Limit: 131072/131072KB (Java/Others)

我还有很多话想和她说,还有很多地方想和她去,把Kaban酱还给我!——Sabaru

薮猫酱为了从天蓝怪手里拯救小包,必须发现天蓝怪们的弱点所在。具体来说,n只天蓝怪组成了一个序列A,每一只有一个战斗力数值Ai,

之后会发生m个事件,事件共有两种类型,有可能是1、薮猫酱给你一个区间[a,b],要你输出max{Ap+Ap+1+…+Aq}(a≤p≤q≤b)max{Ap+Ap+1+…+Aq}(a≤p≤q≤b)2、第pos只天蓝怪的战斗力变成了X。

Input

第一行是两个整数n、m,第二行包含n个整数A1,A2,…,An,接下来m行,每行三个整数,可能是1 a b,代表薮猫酱的一次询问;2 pos X,代表某只天蓝怪战斗力的变化。

Output

对于每次询问,单独输出一行,代表答案。

Sample Input

5 3

1 2 -3 4 5

1 2 3

2 2 -1

1 2 3

Sample Output

2

-1

Hint

1≤n≤500000

1≤m≤100000

−1000≤Ai≤1000

1≤a≤b≤n

1≤pos≤n

−1000≤X≤10000


解题心得:

  1. 这个题就是一个线段树区间合并问题,询问的是一个区间内的最大值并且,多次询问,还要改变某一个点的值,因为是单点,所以可以直接该,不用lazy标记。
  2. 关于线段树的区间合并问题可以看看线段树的区间合并相关问题。这个还更简单。只需要每次维护一个节点左方的最大值,右方的最大值还有整个最大值以及整个区间的和(整个区间的和在合并的时候用来判断一边的最大值是否超过了其中一个子节点)。
  3. 在写这个题的时候写了要给bug,就是在想上更新的时候父节点的一切信息都是又子节点维护而来的,所以父节点的最大值不是从本身的左方的最大值和自身右方的最大值而来,是从子节点的各处维护而来。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5+100;
int n,m;
struct node
{
int l,r,Max,lMax,rMax,sum;
}tree[maxn<<2]; void pushup(int root)
{
tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
tree[root].lMax = max(tree[root<<1].lMax,tree[root<<1].sum + tree[root<<1|1].lMax);
tree[root].rMax = max(tree[root<<1|1].rMax,tree[root<<1|1].sum + tree[root<<1].rMax); //这里要注意父节点的一切信息都是从子节点维护而来的
tree[root].Max = max(tree[root<<1].Max,max(tree[root<<1|1].Max,tree[root<<1].rMax+tree[root<<1|1].lMax));
} void build_tree(int l,int r,int root)
{
tree[root].l = l;
tree[root].r = r;
if(l == r)
{
scanf("%d",&tree[root].Max);
tree[root].lMax = tree[root].rMax = tree[root].Max;
tree[root].sum = tree[root].Max;
return ;
}
int mid = (l + r) >> 1;
build_tree(l,mid,root<<1);
build_tree(mid+1,r,root<<1|1);
pushup(root);
} node query(int L,int R,int l,int r,int root)
{
if(L <= l && R >= r)
{
return tree[root];
}
int mid = (l + r) >> 1;
if(R <= mid)
return query(L,R,l,mid,root<<1);
else if(L > mid)
return query(L,R,mid+1,r,root<<1|1);
else
{
node m1 = query(L,mid,l,mid,root<<1);
node m2 = query(mid+1,R,mid+1,r,root<<1|1);
node m3;
//这里需要将两个树结合起来相比较,所以需要返回一个node
m3.Max = max(m1.Max,max(m2.Max,m1.rMax+m2.lMax));
m3.lMax = max(m1.lMax,m1.sum+m2.lMax);
m3.rMax = max(m2.rMax,m2.sum + m1.rMax);
m3.sum = m2.sum + m1.sum;
return m3;
}
} //单点更新
void change(int pos,int num,int l,int r,int root)
{
if(l == r)
{
tree[root].Max = tree[root].lMax = tree[root].rMax = tree[root].sum = num;
return ;
}
int mid = (l + r) >> 1;
if(pos <= mid)
change(pos,num,l,mid,root<<1);
else if(pos > mid)
change(pos,num,mid+1,r,root<<1|1);
pushup(root);
} int main()
{
while(scanf("%d%d",&n,&m) != EOF)
{
build_tree(1,n,1);
while(m--)
{
int k,a,b;
scanf("%d%d%d",&k,&a,&b);
if(k == 1)
{
node ans = query(a,b,1,n,1);
printf("%d\n",ans.Max);
}
else
{
change(a,b,1,n,1);
}
}
}
}

线段树: CDOJ1598-加帕里公园的friends(区间合并,单点更新)的更多相关文章

  1. 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)

    P4513 小白逛公园 题目背景 小新经常陪小白去公园玩,也就是所谓的遛狗啦… 题目描述 在小新家附近有一条“公园路”,路的一边从南到北依次排着nn个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩 ...

  2. hdu 3308 线段树 区间合并+单点更新+区间查询

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  3. 线段树 || BZOJ1756: Vijos1083 小白逛公园 || P4513 小白逛公园

    题面:小白逛公园 题解: 对于线段树的每个节点除了普通线段树该维护的东西以外,额外维护lsum(与左端点相连的最大连续区间和).rsum(同理)和sum……就行了 代码: #include<cs ...

  4. 线段树模板加模板题POJ3468

    POJ - 3468 整理了个新的线段树的模板,暑期集训的时候学长给的模板,每个节点单单存了自己所要维护的内容,还是少了点.导致在写pushdown的时候,len我会有点难写.所以就整理个新的模板. ...

  5. hdu4973 线段树(题目不错,用了点,段,更新查找还有DFS)

    题意:       给你一个初始序列,初始序列长度n,分别为1 2 3 4 5 ....n,有两种操作 (1)D l r 把l_r之间的数据都复制一遍 1 2 3 4 5 6 D 2 4 = 1 2 ...

  6. HDU 2795 线段树区间最大值,单点更新+二分

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. hdu 1116 敌兵布阵 线段树 区间求和 单点更新

    线段树的基本知识可以先google一下,不是很难理解 线段树功能:update:单点增减 query:区间求和 #include <bits/stdc++.h> #define lson ...

  8. Luogu 3373 - 【模板】线段树 2 - [加乘线段树]

    题目链接:https://www.luogu.org/problemnew/show/P3373 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个 ...

  9. hdoj 1166 敌兵布阵【线段树求区间最大值+单点更新】

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

随机推荐

  1. MS SqlServer之Exec和EXEC SP_EXECUTESQL

    exec执行sql时字符串时,不能给变量赋值,如果要在sql里给变量赋值,请用EXEC SP_EXECUTESQL 示例: 通过 SP_EXECUTESQL 的第2个参数来定义有哪些参数 输出的加OU ...

  2. VS2013使用EF6通过ADO.NET 连接mySql成功步骤

    VS2013使用EF6通过ADO.NET 连接mySql成功步骤 1.安装mysql-for-visualstudio-1.2.6(我用的目前最新版,这个一般安装VS2013就已经有了,没有的话下载一 ...

  3. 【转】 Oracle 中的一些重要V$ 动态性能视图,系统视图和表

    v$database:数据库的信息,如数据库名,创建时间等. v$instance 实例信息,如实例名,启动时间. v$parameter 参数信息,select * from v$parameter ...

  4. asp.net重启web应用程序域

    我把加载到static静态变量中了,是在数据库中存的,这样每次改了一下必须要重启一下web应用程序,每次去iis操作太麻烦了,于是找的了这个重启的办法,一句话代码: System.Web.HttpRu ...

  5. Spring的七种事务传播机制

    概述 当我们调用一个基于Spring的Service接口方法(如UserService#addUser())时,它将运行于Spring管理的事务环境中,Service接口方法可能会在内部调用其它的Se ...

  6. JS将人民币小写金额转换为大写

    /** 数字金额大写转换(可以处理整数,小数,负数) */ function smalltoBIG(n) { var fraction = ['角', '分']; var digit = ['零', ...

  7. Android Error:Could not run build action using Gradle installation

    错误内容: Error:Could not run build action using Gradle installation ‘D:\AndroidStudio\AS2.x\gradle\grad ...

  8. Ecshop数据表结构

    -- 表的结构 `ecs_account_log`CREATE TABLE IF NOT EXISTS `ecs_account_log` (`log_id` mediumint(8) unsigne ...

  9. vijos 1320 清点人数

    背景 NK中学组织同学们去五云山寨参加社会实践活动,按惯例要乘坐火车去.由于NK中学的学生很多,在火车开之前必须清点好人数. 描述 初始时,火车上没有学生:当同学们开始上火车时,年级主任从第一节车厢出 ...

  10. python爬虫之路——基本文件操作

    介绍python如何打开文件和读取数据 新建TXT文档,为追加模式: f=open('c;/wendang/demo.txt','a+') content="abcdefg123456789 ...