SP4487 GSS6 - Can you answer these queries VI

题目描述

https://www.luogu.com.cn/problem/SP4487

Solution

用 $Splay$ 维护即可

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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <iostream>
#include <cstdio>
#define maxn 200010
#define INF 1000000000
using namespace std;

inline int max(int a, int b, int c) { return max(a, max(b, c)); }

int n, m, a[maxn];

#define lc T[i].ch[0]
#define rc T[i].ch[1]
struct Splay {
int sz, cnt, v, ch[2], suf, pre, sum, key;
} T[maxn]; int top, rt, f[maxn];
inline void update(int i) {
if (!i) return ;
T[i].suf = max(T[rc].suf, T[rc].sum + T[i].key + max(0, T[lc].suf));
T[i].pre = max(T[lc].pre, T[lc].sum + T[i].key + max(0, T[rc].pre));
T[i].sum = T[lc].sum + T[rc].sum + T[i].key;
T[i].v = max(T[lc].v, T[rc].v, max(0, T[lc].suf) + T[i].key + max(0, T[rc].pre));
T[i].sz = T[i].cnt + T[lc].sz + T[rc].sz;
}

inline int newnode(int v) {
int i = ++top;
T[i].key = v; T[i].cnt = 1;
return i;
}

void build(int &i, int l, int r, int fa) {
if (l > r) return ;
int m = l + r >> 1; i = newnode(a[m]);
build(lc, l, m - 1, i); build(rc, m + 1, r, i);
f[i] = fa; update(i);
}

inline int get(int i) { return T[f[i]].ch[1] == i; }

inline void rotate(int x) {
int fa = f[x], ffa = f[f[x]], wx = get(x);
f[x] = ffa; f[fa] = x; f[T[x].ch[wx ^ 1]] = fa;
if (ffa) T[ffa].ch[T[ffa].ch[1] == fa] = x;
T[fa].ch[wx] = T[x].ch[wx ^ 1]; T[x].ch[wx ^ 1] = fa;
update(fa); update(x);
}

void Splay(int i, int k = 0) {
for (int fa = f[i]; fa != k; rotate(i), fa = f[i])
if (f[fa] != k) rotate(get(fa) == get(i) ? fa : i);
if (!k) rt = i;
}

int findk(int k) {
int i = rt;
while (1) {
if (k <= T[lc].sz) { i = lc; continue; }
k -= T[lc].sz;
if (k <= T[i].cnt) return Splay(i), i;
k -= T[i].cnt; i = rc;
}
}

void insert(int k, int v) {
int x = findk(k), y = findk(k + 1), i = newnode(v);
Splay(x); Splay(y, x);
T[x].ch[1] = i; T[i].ch[1] = y;
f[y] = i; f[i] = x; update(i); update(x);
}

void del(int k) {
int x = findk(k), y = findk(k + 2), i;
Splay(x); Splay(y, x); i = T[y].ch[0];
f[i] = 0; T[y].ch[0] = 0; update(y); update(x);
}

void replace(int k, int v) {
int x = findk(k + 1); Splay(x);
T[rt].key = v; update(rt);
}

int query(int l, int r) {
int x = findk(l), y = findk(r + 2), i;
Splay(x); Splay(y, x); i = T[y].ch[0];
return T[i].v;
}

inline void solve_1() {
int x, y; scanf("%d%d", &x, &y);
insert(x, y);
}

inline void solve_2() {
int x; scanf("%d", &x);
del(x);
}

inline void solve_3() {
int x, y; scanf("%d%d", &x, &y);
replace(x, y);
}

inline void solve_4() {
int x, y; scanf("%d%d", &x, &y);
printf("%d\n", query(x, y));
}

int main() {
cin >> n; T[0].v = T[0].pre = T[0].suf = -INF;
for (int i = 1; i <= n; ++i) cin >> a[i];
cin >> m; build(rt, 0, n + 1, 0);
for (int i = 1; i <= m; ++i) {
char c[3]; scanf("%s", c + 1);
switch (c[1]) {
case 'I' : solve_1(); break;
case 'D' : solve_2(); break;
case 'R' : solve_3(); break;
case 'Q' : solve_4(); break;
}
}
return 0;
}