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. [Python]round四舍五入精度缺失的解决

    环境: os: win7 64bit python:2.7.5  32bit 对python四舍五入的解决方案 现象: 一般的四舍五入操作都是使用内置的round方法   In [14]: round ...

  2. Linux查找yum安装软件在系统中路径

    find文件查找http://www.ruanyifeng.com/blog/2009/10/5_ways_to_search_for_files_using_the_terminal.html

  3. security Export/import

    export [-k keychain] [-t type] [-f format] [-w] [-p format] [-P passphrase] [-o outfile] Export one ...

  4. java(17) - 增强for循环、装箱拆箱、可变参数

    一.增强型for循环: 语法格式: 打印: A B C D E 当遍历集合或数组时,如果需要访问集合或数组的下标时,最好使用旧的方法来便利或循环,而不要用增强型for循环,因为它丢失了下标信息. 对于 ...

  5. Java里的接口

    Java里面由于不允许多重继承,所以如果要实现多个类的功能,则可以通过实现多个接口来实现. Java接口和Java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现.OOP面向对象的编程,如 ...

  6. CRT远程连接server字符输出乱码解决一例

    CRT远程连接server字符输出乱码解决一例 环境: server:Centos 6.2 远端:win 7 CRT版本号:7.1.1 现象回想: 1.server端:中文字符显示正常,例如以下: 2 ...

  7. Hibernate简单的基础理论

    和Hibernate有关的概念,是掌握Hibernate必须了解的知识.就个人经验来说,可以在了解如何简单开发Hibernate之后,再来学习这些概念,这样可以有个比较清楚的认识.Hibernate是 ...

  8. .NET基础拾遗(7)多线程开发基础4

    一.多线程编程中的线程同步 1.C#中的lock关键字 lock关键字可能是我们在遇到线程同步的需求时最常用的方式,但lock只是一个语法糖,为什么这么说呢,下面慢慢道来. (1)lock的等效代码其 ...

  9. mac os 10.10下安装android studio问题:android studio was unable to find a valid jvm

    友情提示:小编在做到这一步前,已经确定jdk和环境变量已经安装并配置无误,关于怎么检查java环境变量请自行百度. 原因分析:android studio安装包下的info.plist配置文件中有个关 ...

  10. Android-操作栏之副标题

    我们的目标是在操作栏右侧加上一个选项菜单,点击它就可显示或者隐藏操作栏的副标题. 由于操作栏是在API11级以后出现的,因此必须考虑兼容性问题.我们直接让低于API11的设备根本看不到选项菜单即可.建 ...