【线段树维护最大子段和】ACwing 245. 你能回答这些问题吗
2021-05-30 19:49:00 # ACM

题链

线段树维护节点从左边最大,从右边最大,最大子段和,总和,区间最大值;

如果区间最大值小于 $0$,输出区间最大值;

否则输出最大子段和;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#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;
}
Prev
2021-05-30 19:49:00 # ACM
Next