BZOJ 1756: Vijos1083 小白逛公园  (线段树维护单点修改区间查询最大子段和)

 

1756: Vijos1083 小白逛公园

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1078  Solved: 353
[Submit][Status][Discuss]

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
题意:中文题面,不多说。
思路:关于维护最大子段和的问题,做法同

hitoj2687题解

但是和上面这道题不同的是,每次询问的是某个区间的最大字段和,而不是整个区间的最大子段和。

我们的做法是,将查询的区间拆成若干个区间,然后按照pushup中的方法合并。

一个技巧是query的时候返回一个结构体,这样会比较好写。

 

hit oj 2687 Candy (线段树动态维护最大连续子段)

题目链接

题意:给出n个数,m个修改,每次修改后询问整个区间的最大连续子段。

思路:考虑一段区间,分成左右两个子区间,这段区间的最大子段有三种情况:只在左区间中,只在右区间中,既在左区间中又在右区间中。前两种很好维护,对于后一种,我们新增加线段树的两个域,mxl,mxr,分别表示一个区间中包含左端点在的最大字段和(也就是最大前缀和),和一个区间中包含右端点在的最大子段和(也就是最大后缀和),然后对于最大子段既在左区间又在右区间的情况,只需要合并【左区间的最大后缀和 】和【右区间的最大前缀和】就好。

关于一个区间最大前缀和的维护,取该区间的左区间的最大前缀和和【该区间的左区间和】+【该区间的右区间的最大前缀和】的最大值。

最大后缀和同理。

这是一种很经典的做法,注意体会。

1A

 

 

codeforces #327 A. Flipping Game

http://codeforces.com/contest/327/problem/A
题意:给定一段序列,只由0,1组成。要求选一段非空区间,做翻转操作(0变1,1变0),问变完之后1最多能有多少。
思路:最后的1个个数=初始的1的个数+变换区间的0的个数-变换区间的1的个数。初始的是常数。那么我们只要找到某一个区间内,0的个数-1的个数有最大值即可。如果a[i]==0的时候令b[i]=1,否则b[i]=0,那就是经典了最大连续区间和的问题了。dp的思想o(n)可以解决。