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. Java组合与继承生成的类中构造函数的执行顺序

    [程序实例] import java.util.*; class Meal{ Meal() { System.out.println("Meal Constructor"); } ...

  2. 关于springMVC框架访问web-inf下的jsp文件

    问题:springMVC框架访问web-inf下的jsp文件,具体如下: 使用springMVC,一般都会使用springMVC的视图解析器,大概会这样配置 <property name=&qu ...

  3. (转)iOS5:[UIDevice uniqueIdentifier]的替代方案

    背景: 大多数应用都会用到苹果设备的UDID号,UDID通常有以下两种用途: 1)用于一些统计与分析目的:[第三方统计工具如友盟,广告商如ADMOB等] 2)将UDID作为用户ID来唯一识别用户,省去 ...

  4. Android系统如何实现UI的自适应

    做Android应用的人都知道,要一个apk适用多个不同的手机屏幕是很容易的,就是在项目的res文件夹下面有多套相关的资源文件.程序运行的时候,Android系统会根据当前设备的信息去加载不同文件夹下 ...

  5. 300元差价选谁好 魅蓝note对比魅蓝手机

    http://mobile.pconline.com.cn/608/6089437.html [PConline 对比评测]999元的魅蓝note和699元的魅蓝手机先后被发布,代表着魅族中低端手机已 ...

  6. [转]Android重力感应开发

    http://blog.csdn.net/mad1989/article/details/20848181 一.手机中常用的传感器 在Android2.3 gingerbread系统中,google提 ...

  7. jsPlumb开发入门教程(实现html5拖拽连线)

    jsPlumb是一个强大的JavaScript连线库,它可以将html中的元素用箭头.曲线.直线等连接起来,适用于开发Web上的图表.建模工具等.它同时支持jQuery+jQuery UI.MooTo ...

  8. Linux命令之文件与用户权限

    1.文件管理 在Linux里,任何软件和I/O设备都被视为文件.Linux中的文件名最大支持256个字符,分别可以用A-Z.a-z.0-9等字符来命名. 和Windows不同,Linux中文件是区分大 ...

  9. 填坑 - 使用Entity Framework 6 + Sqlite进行DB first开发

    Sqlite团队也是渣啊,到第6代了还不支持Code First. 1.安装运行环境和组件 .安装SQLite的Visual Studio设计器支持 只有安装了它,在[新建ADO.NET实体数据模型] ...

  10. 打破C++ Const 的规则

    从一个C++菜鸟改函数开始 CString MyClass::GetStringValue() const { return m_strValue; } 这个值可能还没有赋值,好吧,那么我先判断是不是 ...