0%

[SP1716] GSS3 - Can you answer these queries III

题目

题目链接

题目大意: 给出 $n$ 个数 $\{a_n\}$. $m$ 次操作, 每次操作将 $a_x$ 改为 $y$ 或查询 $[x, y]$ 中最大子段和. $1 \le n, m \le 50000$.

思路

我们发现这道题跟 GSS1 相比只多了一个单点的修改操作. 我们又知道单点修改的复杂度是 $\log n$ 左右的.

于是我们直接暴力对单点进行修改就行了.

代码

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
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

template <class T>
inline void read(T &x) {
x = 0;
int f = 0;
char ch = getchar();
while (!isdigit(ch)) { f |= ch == '-'; ch = getchar(); }
while (isdigit(ch)) { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); }
x = f ? -x : x;
return ;
}

typedef unsigned long long uLL;
typedef long long LL;

struct Node {
int l, r;
LL v, pre, suf, sum;
} t[200010];

int n, m, l, r, tp;

inline int lson(int x) { return x << 1; }
inline int rson(int x) { return x << 1 | 1; }

void maintain(int x) {
t[x].sum = t[lson(x)].sum + t[rson(x)].sum;
t[x].pre = std::max(t[lson(x)].pre, t[lson(x)].sum + t[rson(x)].pre);
t[x].suf = std::max(t[rson(x)].suf, t[rson(x)].sum + t[lson(x)].suf);
t[x].v = std::max(t[lson(x)].v, std::max(t[rson(x)].v, t[lson(x)].suf + t[rson(x)].pre));
}

void buildTree(int x, int l, int r) {
t[x].l = l, t[x].r = r;
if (l == r) {
read(t[x].v);
t[x].pre = t[x].suf = t[x].sum = t[x].v;
return ;
}
int mid = (l + r) >> 1;
buildTree(lson(x), l, mid), buildTree(rson(x), mid + 1, r);
maintain(x);
}

void modify(int x, int pos, LL d) {
if (t[x].l == t[x].r && t[x].l == pos) {
t[x].v = t[x].pre = t[x].suf = t[x].sum = d;
return ;
}
int mid = (t[x].l + t[x].r) >> 1;
if (pos <= mid) modify(lson(x), pos, d);
else modify(rson(x), pos, d);
maintain(x);
}

Node query(int x, int l, int r) {
if (l <= t[x].l && r >= t[x].r) return t[x];
int mid = (t[x].l + t[x].r) >> 1;
if (l > mid) return query(rson(x), l, r);
if (r <= mid) return query(lson(x), l, r);
Node now, ls = query(lson(x), l, r), rs = query(rson(x), l, r);
now.sum = ls.sum + rs.sum;
now.pre = std::max(ls.pre, ls.sum + rs.pre);
now.suf = std::max(rs.suf, rs.sum + ls.suf);
now.v = std::max(ls.v, std::max(rs.v, ls.suf + rs.pre));
return now;
}

int main() {
read(n);
buildTree(1, 1, n);
read(m);
while (m--) {
read(tp), read(l), read(r);
if (!tp) {
modify(1, l, r * 1LL);
} else {
printf("%lld\n", query(1, l, r).v);
}
}
return 0;
}