ACwing 245. 你能回答这些问题吗
线段树维护节点从左边最大,从右边最大,最大子段和,总和,区间最大值;
如果区间最大值小于 0,输出区间最大值;
否则输出最大子段和;
#include <bits/stdc++.h>
using namespace std;
#define ls rt<<1
#define rs rt<<1|1
#define LL long long
#define ll long long
#define PI acos(-1.0)
#define eps 1e-8
#define Pair pair<double,double>
// notice
#define mod 998244353
#define MAXN 1e18
#define MS 1000009
LL n,m;
struct node{
LL lmax,rmax;
LL maxn;
LL sum;
LL maxval;
}p[MS<<2];
void push_up(int rt){
p[rt].sum = p[ls].sum + p[rs].sum;
p[rt].maxval = max(p[ls].maxval,p[rs].maxval);
p[rt].lmax = max(p[ls].lmax ,p[ls].sum + p[rs].lmax);
p[rt].rmax = max(p[rs].rmax ,p[rs].sum + p[ls].rmax);
p[rt].maxn = max(p[rt].lmax,p[rt].rmax);
p[rt].maxn = max(p[rt].maxn,max(p[ls].maxn,p[rs].maxn));
}
void build(int l,int r,int rt){
if(l == r){
LL x;
cin >> x;
p[rt] = {max(0ll,x),max(0ll,x),max(0ll,x),x,x};
return;
}
int m = l+r>>1;
build(l,m,ls);
build(m+1,r,rs);
push_up(rt);
}
void update(int pos,int l,int r,int rt,LL val){
if(l == r){
p[rt] = {max(0ll,val),max(0ll,val),max(0ll,val),val,val};
return;
}
int m = l+r>>1;
if(m >= pos) update(pos,l,m,ls,val);
if(m < pos) update(pos,m+1,r,rs,val);
push_up(rt);
}
node query(int L,int R,int l,int r,int rt){
if(L <= l && r <= R){
return p[rt];
}
int m = l+r>>1;
if(m < L) return query(L,R,m+1,r,rs);
else if(m >= R) return query(L,R,l,m,ls);
else{
node tl = query(L,R,l,m,ls);
node tr = query(L,R,m+1,r,rs);
node ans;
ans.sum = tl.sum + tr.sum;
ans.maxval = max(tl.maxval,tr.maxval);
ans.lmax = max(tl.lmax ,tl.sum + tr.lmax);
ans.rmax = max(tr.rmax ,tr.sum + tl.rmax);
ans.maxn = max(ans.lmax,ans.rmax);
ans.maxn = max(ans.maxn ,max(tl.maxn ,tr.maxn));
return ans;
}
}
int main() {
ios::sync_with_stdio(false);
cin >> n >> m;
build(1,n,1);
while(m--){
int op,l,r,pos,val;
cin >> op;
if(op == 1){
cin >> l >> r;
if(l > r) swap(l,r);
node ans = query(l,r,1,n,1);
if(ans.maxval < 0){
cout << ans.maxval << "\n";
}
else{
cout << ans.maxn << "\n";
}
}
else if(op == 2){
cin >> pos >> val;
update(pos,1,n,1,val);
}
}
return 0;
}

浙公网安备 33010602011771号