5t0_0r2 @ 2024-10-10 18:04:33
这是我的 AC 代码:
#include<bits/stdc++.h>
#define int long long
#define mid ((l + r) >> 1)
#define lchild (root << 1)
#define rchild ((root << 1) + 1)
using namespace std;
const int N = 5e5 + 9,INF = 1e9;
int n,m;
int a[N];
struct node{
int sum,val;//区间和、区间最大子段和
int lsum,rsum;//前缀最大和、后缀最大和
} t[N << 2];
bool in_range(int l,int r,int L,int R){
return L <= l && r <= R;
}
bool out_range(int l,int r,int L,int R){
return r < L || l > R;
}
void push_up(int root){
t[root].sum = t[lchild].sum + t[rchild].sum;
t[root].val = max(max(t[lchild].val,t[rchild].val),t[lchild].rsum + t[rchild].lsum);
t[root].lsum = max(t[lchild].lsum,t[lchild].sum + t[rchild].lsum);
t[root].rsum = max(t[rchild].rsum,t[rchild].sum + t[lchild].rsum);
}
void build(int root,int l,int r){
if(l == r){
t[root].sum = t[root].val = t[root].lsum = t[root].rsum = a[l];//该题的最大子段和不能不选,所以单位长度的区间最大子段和为该位置上的值
return;
}
build(lchild,l,mid);
build(rchild,mid + 1,r);
push_up(root);
}
node query(int root,int l,int r,int L,int R){
if(out_range(l,r,L,R))
return (node){-INF,-INF,-INF,-INF};//这里第一项要写0,在本题中没有寄,但在GSS5中寄了
if(in_range(l,r,L,R))
return t[root];
node ql = query(lchild,l,mid,L,R),qr = query(rchild,mid + 1,r,L,R);
return (node){
ql.sum + qr.sum,
max(max(ql.val,qr.val),ql.rsum + qr.lsum),
max(ql.lsum,ql.sum + qr.lsum),
max(qr.rsum,qr.sum + ql.rsum)
};
}
void update(int root,int l,int r,int pos,int v){
if(l == r){
t[root].sum = t[root].val = t[root].lsum = t[root].rsum = v;
return;
}
if(pos <= mid)
update(lchild,l,mid,pos,v);
else
update(rchild,mid + 1,r,pos,v);
push_up(root);
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n >> m;
for(int i = 1;i <= n;i++)
cin >> a[i];
build(1,1,n);
while(m--){
int op;
cin >> op;
if(op == 1){
int l,r;
cin >> l >> r;
if(l > r)
swap(l,r);
cout << query(1,1,n,l,r).val << '\n';
}
else if(op == 2){
int pos,v;
cin >> pos >> v;
update(1,1,n,pos,v);
}
}
return 0;
}
求解答。