算法学习专栏——线段树——最长子序列(板子题)

题型二:最长连续子序列

你能回答这些问题吗

题目

给定长度为 N 的数列 A,以及 M 条指令,每条指令可能是以下两种之一:

  1. 1 x y,查询区间 [x,y] 中的最大连续子段和,即 image-20240516195545288
  2. 2 x y,把 A[x]改成 y。

对于每个查询指令,输出一个整数表示答案。

输入格式

第一行两个整数 N,M,。

第二行 N 个整数 A[i]。

接下来 M 行每行 3 个整数 k,x,y,k=1 表示查询(此时如果 x>y,请交换 x,y,),k=2 表示修改。

输出格式

对于每个查询指令输出一个整数表示答案。

每个答案占一行。

数据范围

N≤500000,M≤100000
−1000≤A[i]≤1000

输入样例:

1
2
3
4
5
5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 3 2

输出样例:

1
2
2
-1

思路(百度之星之后准备开视频讲解)

​ 这道题目是线段树的经典题型.解决的是求子区间和最大值问题.

代码

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
#include <bits/stdc++.h>

// #define int long long
#define ed '\n'
#define fi first
#define se second
#define fore(i, l, r) for(int i = (int)(l); i <=(int)r; i++)
#define out(x, k) cout << fixed << setprecision(k) << x << ed

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;
typedef double db;


const int INF = 1e9;
const int N = 5e5 + 10;

int n, m;
int w[N];
struct Node{
int l, r, sum;
int lv, rv;
int v;
}tr[4 * N];

void pushup(Node &u,Node &l,Node &r) {
u.sum = l.sum + r.sum;
u.lv = max(l.lv, l.sum + r.lv);
u.rv = max(r.rv, r.sum + l.rv);
u.v = max({l.v, r.v, l.rv + r.lv});
}

void pushup(int u) {
pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

void build(int u, int l, int r) {
if (l == r) tr[u] = {l, r, w[r], w[r], w[r], w[r]};
else {
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}

void modify(int u, int x, int v) {
if (tr[u].l == x && tr[u].r == x) tr[u] = {x, x, v, v, v, v};
else {
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) modify(u << 1, x, v);
else modify(u << 1 | 1, x, v);
pushup(u);
}
}

Node query(int u, int l, int r) {
if (tr[u].l >= l && tr[u].r <= r) return tr[u];
else {
int mid = tr[u].l + tr[u].r >> 1;
if (r <= mid) return query(u << 1, l, r);
else if (l > mid) return query(u << 1 | 1, l, r);
else {
auto left = query(u << 1, l, r);
auto right = query(u << 1 | 1, l, r);
Node ans;
pushup(ans, left, right);
return ans;
}
}
}
void solve() {
cin >> n >> m;
fore (i, 1, n) cin >> w[i];
build(1, 1, n);
while (m--) {
int k, x, y;
cin >> k >> x >> y;
if (k == 1) {
if (x > y) swap(x, y);
cout << query(1, x, y).v << ed;
} else {
modify(1, x, y);
}
}
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _ = 1;
// cin >> _;

while(_--) {
solve();
}
return 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
// #include <iostream>
// #include <cstring>
// #include <algorithm>
// #include <queue>
// #include <map>
// #include <unordered_map>
// #include <string>
// #include <cmath>
// #include <set>
// #include <stack>
// #include <vector>
// #include <deque>
// #include <bitset>
// #include <cstdio>
// #include <iomanip>

// // #define int long long
// #define ull unsigned long long
// #define ed '\n'
// #define fi first
// #define se second
// #define fore(i, l, r) for(int i = (int)(l); i <=(int)r; i++)
// #define debug(x) cout << "#x = " << x << ed;
// #define PI acos(-1)
// #define E exp(1)
// #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
// #define me0(st) memset(st, 0, sizeof st)
// #define me3f(st) memset(st, 0x3f, sizeof st)
// #define pdf(x) printf("%lf", double(x))
// #define pif(x) printf("%d ", int(x))
// #define scf(x) printf("%d", int(x))
// #define re return 0
// #define max(a, b) ((a) > (b) ? (a) : (b))
// #define min(a, b) ((a) < (b) ? (a) : (b))
// #define out(x, k) cout << fixed << setprecision(k) << x << ed

// using namespace std;

// typedef pair<int, int> PII;
// typedef long long LL;
// typedef double db;


// const int INF = 1e9;
// const int N = 1e5 + 10;

// struct Node {
// int l, r;
// LL sum, add, mul;
// }tr[4 * N];
// int n, q, m;
// LL w[N];

// void pushdown(int u) {
// auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];

// // add类型
// if (root.add)
// left.add += root.add, left.sum += LL(root.add * (left.r - left.l + 1) % m);
// right.add += root.add, right.sum += LL(root.add * (right.r - right.l + 1) % m);

// // mul类型
// left.mul *= root.mul, left.sum = LL(left.sum * root.mul + root.add * left.sum % m);
// right.mul *= root.mul, right.sum = LL(right.sum * root.mul + root.add * right.sum % m);

// root.mul = 1;
// root.add = 0;
// }

// void pushup(int u) {
// tr[u].sum = (tr[u << 1].sum + tr[u << 1 | 1].sum) % m;
// }

// void build(int u, int l, int r) {
// if (l == r) tr[u] = {l, r, w[r], 0, 1};
// else {
// tr[u] = {l, r, 0, 0, 1};
// int mid = l + r >> 1;
// build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
// pushup(u);
// }
// }

// // 和
// void modify1(int u,int l, int r, int d) {
// if (tr[u].l >= l && tr[u].r <= r) {
// tr[u].sum = (LL)((tr[u].sum + (tr[u].r - tr[u].l + 1) * d) % m);
// tr[u].add += d;
// } else {
// pushdown(u);
// int mid = tr[u].l + tr[u].r >> 1;
// if (l <= mid) modify1(u << 1, l, r, d);
// if (r > mid) modify1(u << 1 | 1, l, r, d);
// pushup(u);
// }
// }

// // 积
// void modify2(int u, int l, int r, int d) {
// if (tr[u].l >= l && tr[u].r <= r) {
// tr[u].sum = (tr[u].sum * d) % m;
// tr[u].add = (tr[u].add * d) % m;
// tr[u].mul =(tr[u].mul * d) % m;
// } else {
// pushdown(u);
// int mid = tr[u].l + tr[u].r >> 1;
// if (l <= mid) modify2(u << 1, l, r, d);
// if (r > mid) modify2(u << 1 | 1, l, r, d);
// pushup(u);
// }
// }

// LL query(int u, int l, int r) {
// if (tr[u].l >= l && tr[u].r <= r) {
// return tr[u].sum;
// }
// else {
// pushdown(u);
// int mid = tr[u].l + tr[u].r >> 1;
// LL sum = 0;
// if (l <= mid) sum = query(u << 1, l, r);
// if (r > mid) sum += query(u << 1 | 1, l, r);
// return sum;
// }
// }

// void solve() {
// scanf("%d %d %d", &n, &q, &m);
// for (int i = 1; i <= n; i++) scanf("%lld", &w[i]);
// build(1, 1, n);

// int l, r, d;
// char op[2];
// while (q--) {
// scanf("%s %d %d", op, &l, &r);
// if (*op == '1') {
// scanf("%d",&d);
// modify1(1, l, r, d);
// } else if (*op == '2') {
// scanf("%d",&d);
// modify2(1, l, r, d);
// } else {
// printf("%lld\n", query(1, l, r));
// }
// }
// }
// int main()
// {
// IOS;
// int _ = 1;
// // cin >> _;

// while(_--) {
// solve();
// }

// re;
// }

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <unordered_map>
#include <string>
#include <cmath>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <bitset>
#include <cstdio>
#include <iomanip>

// #define int long long
#define ull unsigned long long
#define ed '\n'
#define fi first
#define se second
#define fore(i, l, r) for(int i = (int)(l); i <=(int)r; i++)
#define debug(x) cout << "#x = " << x << ed;
#define PI acos(-1)
#define E exp(1)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define me0(st) memset(st, 0, sizeof st)
#define me3f(st) memset(st, 0x3f, sizeof st)
#define pdf(x) printf("%lf", double(x))
#define pif(x) printf("%d ", int(x))
#define scf(x) printf("%d", int(x))
#define re return 0
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define out(x, k) cout << fixed << setprecision(k) << x << ed

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;
typedef double db;


const int INF = 1e9;
const int N = 2e5 + 10;
bool st[30];
char s[N], s0[30];
map<char, char> mp;

void solve() {
int n;
scanf("%d %s", &n, s);

fore (i, 1, n) {
st[s[i] - 'a'] = true;
}
int k = 0;

fore (i, 0, 25) {
if (st[i]) s0[k++] = 'a' + i;
}

fore (i, 0, k - 1) {
mp[s0[k - i - 1]] = mp[s0[i]];
mp[s0[i]] = mp[s0[k - i - 1]];
}

fore (i, 1, n) {
s[i] = mp[s[i]];
}

fore (i, 1, n) printf("%c ", s[i]);
puts("");
}

int main()
{
// IOS;
int _ = 1;
cin >> _;

while(_--) {
solve();
}

re;
}