题意
给出一个序列,给出
M
M
M次操作,按照要求输出。
“
2
“2
“2
x
x
x
y
”
y”
y”,把
A
[
x
]
A[x]
A[x]改成
y
y
y。
“
1
“1
“1
x
x
x
y
”
y”
y”,查询区间
[
x
,
y
]
[x,y]
[x,y]中的最大连续子段和。
思路
我们可以用线段树来维护区间的最大连续子段和。
新开四个变量
d
a
t
,
s
u
m
,
l
m
a
x
,
r
m
a
x
dat,sum,lmax,rmax
dat,sum,lmax,rmax分别代表这个区间的最大连续子段和、区间和、靠左端的最大子段和、靠右端的最大子段和。
然后在
b
u
i
l
d
build
build和
c
h
a
n
g
e
change
change操作时改一改就好了。
代码
#include<cstdio>
#include<algorithm>
#define lson(p) (p) << 1
#define rson(p) ((p) << 1) | 1
using namespace std;
int n, m, a[500001], x, y, z;
struct node{
int dat, sum, lmax, rmax, l, r;
}t[2000001];
void build(int p, int l, int r) {//建树
t[p].l = l;
t[p].r = r;
if (l == r) {
t[p].dat = a[l];
t[p].sum = a[l];
t[p].lmax = a[l];
t[p].rmax = a[l];
return;
}
int mid = (l + r) >> 1;
build(lson(p), l, mid);
build(rson(p), mid + 1, r);
t[p].sum = t[lson(p)].sum + t[rson(p)].sum;
t[p].lmax = max(t[lson(p)].lmax, t[lson(p)].sum + t[rson(p)].lmax);
t[p].rmax = max(t[rson(p)].rmax, t[rson(p)].sum + t[lson(p)].rmax);
t[p].dat = max(max(t[lson(p)].dat, t[rson(p)].dat), t[lson(p)].rmax + t[rson(p)].lmax);
}
node ask(int p, int l, int r) {//查找
if (t[p].l == l && t[p].r == r) return t[p];
int mid = (t[p].l + t[p].r) >> 1;
if (r <= mid) return ask(lson(p), l, r);
else if (l > mid) return ask(rson(p), l, r);
else {
node a = ask(lson(p), l, mid);
node b = ask(rson(p), mid + 1, r);
node c;
c.sum = a.sum + b.sum;
c.lmax = max(a.lmax, a.sum + b.lmax);
c.rmax = max(b.rmax, b.sum + a.rmax);
c.dat = max(max(a.dat, b.dat), a.rmax + b.lmax);
return c;
}
}
void change(int p, int x, int v) {//修改
if (t[p].l == t[p].r) {
t[p].sum = v;
t[p].dat = v;
t[p].lmax = v;
t[p].rmax = v;
return;
}
int mid = (t[p].l + t[p].r) >> 1;
if (x <= mid) change(lson(p), x, v);
else change(rson(p), x, v);
t[p].dat = max(max(t[lson(p)].dat, t[rson(p)].dat), t[lson(p)].rmax + t[rson(p)].lmax);
t[p].sum = t[lson(p)].sum + t[rson(p)].sum;
t[p].lmax = max(t[lson(p)].lmax, t[lson(p)].sum + t[rson(p)].lmax);
t[p].rmax = max(t[rson(p)].rmax, t[rson(p)].sum + t[lson(p)].rmax);
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(1, 1, n);
while (m--) {
scanf("%d %d %d", &z, &x, &y);
if (z == 1) {
if (x > y) swap(x, y);
printf("%d\n", ask(1, x, y).dat);
}
else change(1, x, y);
}
return 0;
}