加帕里公园的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. Windows和Ubuntu使用网线直连搭建局域网

    1.Windows下的配置:右键右下角的网络图标(或者右键网络→属性)→更改适配器设置→以太网→右键属性→TCP/IPv4→IP地址(192.168.1.3)→子网掩码(255.255.255.0)→ ...

  2. openstack安装newton版本dashboard+cinder(六)

    一.dashboard 1.安装dashboard及配置 [root@linux-node1 ~]# yum install openstack-dashboard -y #可以装任何地方只要能连接 ...

  3. ms sqlserver 登录失败 错误:4064

    无法打开用户默认数据库.登录失败.用户‘sa’登录失败.(Microsoft SQL Server, 错误:4064) 解决方法:解决方法:先用windows身份验证的方式登录进去,然后在 安全性=& ...

  4. webpack分开打包和合并打包的瘦身

    webpack.config.js 记录一下优化webpack的几个点: 1.     devtool: false,   //产品阶段不应该有devtool entry: { bundle : pa ...

  5. linux-2.6.22.6/Makefile:416: *** mixed implicit and normal rules: deprecated syntax

    今天在按照韦东山大哥的教程流程编译内核的时候出现了这个问题      linux-2.6.22.6/Makefile:416: *** mixed implicit and normal rules: ...

  6. rest_framework序列化组件

    一.Django自带的序列化组件  ==>对象序列化成json格式的字符串 from django.core import serializers from django.core import ...

  7. ZR#331. 【18 提高 3】括号序列(栈)

    题意 挺神仙的.首先$60$分暴力是比较好打的. 就是枚举左端点,看右端点能否是$0$ 但是这样肯定是过不了的,假如我们只枚举一次,把得到的栈记录下来 那么若区间$(l, r)$是可行的,那么$s_{ ...

  8. 在开发第一个Android应用之前需要知道的5件事:

    你能否详细讲述一下,在开发Android应用过程中每一阶段要用到的技能和编程语言? 建立一个Android应用程序可以归结为两个主要技能/语言:Java和Android系统.Java是Android的 ...

  9. GIT新手入门学习教程

    廖雪峰的GIT教程 链接地址:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

  10. Linux 的数字权限意义

    三个组 每个都有三个权限 r w x每个权限用二进制 0 和 1 标示 1即为有此权限 0 标示无权限  ower    group  other  r w x    r w x  r w x 每个组 ...