小白逛公园
题目背景
小新经常陪小白去公园玩,也就是所谓的遛狗啦…
题目描述
在小新家附近有一条“公园路”,路的一边从南到北依次排着 n n n 个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了。
一开始,小白就根据公园的风景给每个公园打了分。小新为了省事,每次遛狗的时候都会事先规定一个范围,小白只可以选择第 a a a 个和第 b b b 个公园之间(包括 a , b a, b a,b 两个公园)选择连续的一些公园玩。小白当然希望选出的公园的分数总和尽量高咯。同时,由于一些公园的景观会有所改变,所以,小白的打分也可能会有一些变化。
那么,就请你来帮小白选择公园吧。
输入格式
第一行,两个整数 n n n 和 m m m,分别表示表示公园的数量和操作(遛狗或者改变打分)总数。
接下来 n n n 行,每行一个整数,依次给出小白开始时对公园的打分。
接下来 m m m 行,每行三个整数。其中第一个整数 k k k 为 1 1 1 或 2 2 2。
- k = 1 k=1 k=1 表示,小新要带小白出去玩,接下来的两个整数 a a a 和 b b b 给出了选择公园的范围 ( 1 ≤ a , b ≤ n ) (1 \le a,b \le n) (1≤a,b≤n)。测试数据可能会出现 a > b a > b a>b 的情况,需要进行交换;
- k = 2 k=2 k=2 表示,小白改变了对某个公园的打分,接下来的两个整数 p p p 和 s s s,表示小白对第 p p p 个公园的打分变成了 s ( 1 ≤ p ≤ N ) s(1\le p\le N) s(1≤p≤N)。
输出格式
小白每出去玩一次,都对应输出一行,只包含一个整数,表示小白可以选出的公园得分和的最大值。
样例 #1
样例输入 #1
5 3
1
2
-3
4
5
1 2 3
2 2 -1
1 2 3
样例输出 #1
2
-1
提示
数据规模与约定
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 5 × 1 0 5 1 \le n \le 5 \times 10^5 1≤n≤5×105, 1 ≤ m ≤ 1 0 5 1 \le m \le 10^5 1≤m≤105,所有打分都是绝对值不超过 1000 1000 1000 的整数。
思路
我怎么感觉它跟这道题很像 链接
代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 5e5+10;
struct E{
int l,r;
int tmax;//最大子段和
int lmax;//最大前缀和
int rmax;//最大后缀和
int sum;//区间和
}tr[N*4];
int w[N];
int n,m;
void pushup(E &u,E &l,E &r){
u.sum=l.sum+r.sum;
u.rmax=max(r.rmax,l.rmax+r.sum);
u.lmax=max(l.lmax,l.sum+r.lmax);//分为没有横跨区间和横跨区间
u.tmax=max(max(l.tmax,r.tmax),l.rmax+r.lmax);
}
void pushup(int u){
pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}
void build(int u,int l,int r){
if(l==r) tr[u]={l,r,w[r],w[r],w[r],w[r]};
else{
tr[u]={l,r};
int mid=(l+r)>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
}
E query(int u,int l,int r){
if(tr[u].l>=l&&tr[u].r<=r)return tr[u];//被包围了,不用再继续切分
int mid=(tr[u].l+tr[u].r)>>1;
int v=-1e9;
if(l>mid) return query(u<<1|1,l,r);
if(r<=mid) return query(u<<1,l,r);
E L=query(u<<1,l,r);
E R=query(u<<1|1,l,r);
E res;
pushup(res,L,R);
return res;
}
void modify(int u,int x,int c){
if(tr[u].l==x&&tr[u].r==x)tr[u]={x,x,c,c,c,c};
else{
int mid=(tr[u].l+tr[u].r)>>1;
if(x<=mid)modify(u<<1,x,c);
else modify(u<<1|1,x,c);
pushup(u);
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>w[i];
build(1,1,n);
while(m--){
int k,x,y;
cin>>k>>x>>y;
if(k==1){
if(x>y)swap(x,y);
cout<<query(1,x,y).tmax<<endl;
}else{
modify(1,x,y);
}
}
return 0;
}