Description

小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了。   一开始,小白就根据公园的风景给每个公园打了分-.-。小新为了省事,每次遛狗的时候都会事先规定一个范围,小白只可以选择第a个和第b个公园之间(包括a、b两个公园)选择连续的一些公园玩。小白当然希望选出的公园的分数总和尽量高咯。同时,由于一些公园的景观会有所改变,所以,小白的打分也可能会有一些变化。   那么,就请你来帮小白选择公园吧。

Input

第一行,两个整数N和M,分别表示表示公园的数量和操作(遛狗或者改变打分)总数。 接下来N行,每行一个整数,依次给出小白 开始时对公园的打分。 接下来M行,每行三个整数。第一个整数K,1或2。K=1表示,小新要带小白出去玩,接下来的两个整数a和b给出了选择公园的范围(1≤a,b≤N);K=2表示,小白改变了对某个公园的打分,接下来的两个整数p和s,表示小白对第p个公园的打分变成了s(1≤p≤N)。 其中,1≤N≤500 000,1≤M≤100 000,所有打分都是绝对值不超过1000的整数。

Output

小白每出去玩一次,都对应输出一行,只包含一个整数,表示小白可以选出的公园得分和的最大值。

Sample Input

5 3

1 2 -3 4 5

1 2 3

2 2 -1

1 2 3

Sample Output

2

-1

有一点坑的线段树……你需要特殊的写代码技巧

每个线段树节点要保存几个数据:lm从左节点往右能取到的最大值,rm从右节点往左能取到的最大值。ans保存当前区间任取一段的最大值

因为是单点更新,所以连lazy tag也不需要,精华在于询问和标记上传的函数

上传标记的时候要更新好多东西:

区间和tot:最简单,左边加右边

lm:可以取左边的一整段加右边的lm,或者只取左边的lm。lm=max(左边的tot+右边的lm,左边的lm)

rm:可以取右边的一整段加左边的rm,或者只取右边的rm。rm=max(右边的tot+左边的rm,右边的rm)

ans:可以取更新完的当前的lm、rm,或者取左边的rm加右边的lm

然后询问的时候函数的返回值要是一个线段树的节点而不只是一个数据答案

因为从左右转移的时候,你不知道这个答案是从左边的rm还是ans转移而来,右边也是

具体来说,如果左边从rm转移而来,那么它可以和右边的lm合并,而ans不能保证会“紧贴“在区间的右边,就不能和右边的lm合并

所以要返回一个线段树的节点,然后一切都简单了

#include<cstdio>
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void swap(int &a,int &b){int t=a;a=b;b=t;}
inline int max(int a,int b){if (a>b)return a;else return b;}
struct trees{int l,r,ls,rs,lm,rm,ans,tot;}tree[2000001];
int n,m,a[500001],treesize;
inline void update(int k)
{
int ll=tree[k].ls,rr=tree[k].rs;
tree[k].tot=tree[ll].tot+tree[rr].tot;
tree[k].lm=max(tree[ll].lm,tree[ll].tot+tree[rr].lm);
tree[k].rm=max(tree[rr].rm,tree[rr].tot+tree[ll].rm);
tree[k].ans=max(max(tree[ll].ans,tree[rr].ans),tree[ll].rm+tree[rr].lm);
}
inline void buildtree(int l,int r)
{
if (l>r) return;
int now=++treesize;
tree[now].l=l;tree[now].r=r;
if (l==r)
{
tree[now].tot=tree[now].lm=tree[now].rm=tree[now].ans=a[l];
return;
}
int mid=(l+r)>>1;
tree[now].ls=treesize+1;
buildtree(l,mid);
tree[now].rs=treesize+1;
buildtree(mid+1,r);
update(now);
}
inline trees ask(int k,int l,int r)
{
int x=tree[k].l,y=tree[k].r;
if (l==x&&r==y) return tree[k];
int mid=(x+y)>>1,ll=tree[k].ls,rr=tree[k].rs;
if(r<=mid) return ask(ll,l,r);
else if (l>mid) return ask(rr,l,r);
else
{
trees t_ans;
trees t1=ask(ll,l,mid);
trees t2=ask(rr,mid+1,r);
t_ans.ans=max(max(t1.ans,t2.ans),t1.rm+t2.lm);
t_ans.rm=max(tree[rr].rm,tree[rr].tot+t1.rm);
t_ans.lm=max(tree[ll].lm,tree[ll].tot+t2.lm);
return t_ans;
}
}
inline void change(int k,int to,int dat)
{
int x=tree[k].l,y=tree[k].r;
if (x==y)
{
tree[k].tot=tree[k].lm=tree[k].rm=tree[k].ans=dat;
return;
}
int mid=(x+y)>>1;
if (to<=mid)change(tree[k].ls,to,dat);
if (to>mid)change(tree[k].rs,to,dat);
update(k);
}
int main()
{
n=read();m=read();
for (int i=1;i<=n;i++)
a[i]=read();
buildtree(1,n);
for (int i=1;i<=m;i++)
{
int x=read(),y=read(),z=read();
if (x==1)
{
if (y>z) swap(y,z);
printf("%d\n",ask(1,y,z).ans);
}else change(1,y,z);
}
return 0;
}

bzoj1756 Vijos1083 小白逛公园的更多相关文章

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

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

  2. 【线段树】bzoj1756 Vijos1083 小白逛公园

    我们知道,求一段序列的最大子段和是O(n)的,但是这样是显然会超时的. 我们需要一个数据结构来支持修改和计算的操作,对于这种修改一个而查询区间的问题,考虑使用线段树. 在线段树中,除了左端点,右端点, ...

  3. Bzoj 1756: Vijos1083 小白逛公园 线段树

    1756: Vijos1083 小白逛公园 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1021  Solved: 326[Submit][Statu ...

  4. BZOJ 1756: Vijos1083 小白逛公园

    题目 1756: Vijos1083 小白逛公园 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 856  Solved: 264[Submit][Sta ...

  5. 【Vijos1083/BZOJ1756】小白逛公园(线段树)

    [写在前面]TYC (Little White) 真是太巨啦! 题目: Vijos1083 分析: 一眼看上去就是线段树啊-- 然而当我这种蒟蒻兴高采烈地把线段树模板敲了一半,却发现一个问题: 这子区 ...

  6. 【BZOJ】1756: Vijos1083 小白逛公园(线段树)

    题目 传送门:QWQ 分析 线段树维护一下最大子序列 维护一下最大前缀 最大后缀  区间和 就ok了 好像只能用结构体..... 代码 #include <bits/stdc++.h> u ...

  7. [日常摸鱼]Vijos1083小白逛公园-线段树

    题意:单点修改,询问区间最大子段和,$n\leq 5e5$ 考虑分治的方法$O(nlogn)$求一次最大子段和的做法,我们是根据中点分成左右两个区间,那么整个区间的答案要么是左边答案,要么是右边答案, ...

  8. vijos1083:小白逛公园

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

  9. [vijos P1083] 小白逛公园

    不知怎地竟有种错觉此题最近做过= =目测是类似的?那道题貌似是纯动归? 本来今晚想做两道题的,一道是本题,一道是P1653疯狂的方格取数或NOI08 Employee,看看现在的时间目测这个目标又达不 ...

随机推荐

  1. mysql 索引相关知识

    由where 1 =1 引发的思考 最近工作上被说了 说代码中不能用 where 1=1,当时觉得是应该可以用的,但是找不到什么理据, 而且mysql 语句优化这方面确实很薄弱   感觉自己mysql ...

  2. Java ConcurrentHashmap 解析

    总体描述: concurrentHashmap是为了高并发而实现,内部采用分离锁的设计,有效地避开了热点访问.而对于每个分段,ConcurrentHashmap采用final和内存可见修饰符Volat ...

  3. iOS中XMPP简单聊天实现 好友和聊天

    版权声明本文由陈怀哲首发自简书:http://www.jianshu.com/users/9f2e536b78fd/latest_articles;微信公众号:陈怀哲(chenhuaizhe2016) ...

  4. (转)Linux下apache限速和限制同一IP连接数的实现

    单位有一台DELL的服务器,4核双CPU,4G内存,1TB的存储空间,闲来无事,申请了域名http://www.zxzy123.cn,做了个网站,本以为用这样的配置做个下载站是绰绰有余了,没想到上线没 ...

  5. SUSE 在Intel举行&quot;Rule The Stack&quot;的竞赛中获得 &quot;Openstack安装最高速&quot;奖

    有关"Rule The Stack": https://communities.intel.com/community/itpeernetwork/datastack/blog/2 ...

  6. Java调用天气Webservice的小应用

    废话不多说,直接贴代码: CityReq.java package com.weather; import javax.xml.bind.annotation.XmlElement; import j ...

  7. ibatis中的resultClass,parameterClass,resultMap,resultType的使用与区别

    parameterClass 是参数类.指定了参数的完整类名(包括包路径).可通过别名避免每次重复书写冗长的类名. resultClass 是结果类, 二.resultClass取值 1.result ...

  8. C# Interface显式实现和隐式实现

    c#中对接口的实现方式有两种:隐式实现和显式实现,之前一直没仔细看过,今天查了些资料,在这里整理一下. 隐式实现的例子 interface IChinese { string Speak(); } p ...

  9. javascript获取标签样式(获取背景为例)

    function getStyle(el){ if(window.getComputedStyle){ return window.getComputedStyle(el,null); } retur ...

  10. python 下的数据结构与算法---5:递归(Recursion)

    定义:递归就是不断分割整体成部分直到可以轻易解决分割出来的部分. 递归表达式三定律: 1:递归表达式必须有个最小单元     (最小单元既是停止递归调用以及能够直接运算的) 2:递归表达式在运算过程中 ...