1275. 最大数
摘要
Title: 1275. 最大数
Tag: 线段树
Memory Limit: 64 MB
Time Limit: 1000 ms
Powered by:NEFU AB-IN
1275. 最大数
-
题意
给定一个正整数数列 a1,a2,…,an,每一个数都在 0∼p−1之间。
可以对这列数进行两种操作:
添加操作:向序列后添加一个数,序列长度变成 n+1;
询问操作:询问这个序列中最后 L个数中最大的数是多少。
程序运行的最开始,整数序列为空。
一共要对整数序列进行 m次操作。
写一个程序,读入操作的序列,并输出询问操作的答案。 -
思路
添加操作:向序列后添加一个数,序列长度变成 n+1
- 可以这么实现:先用线段树开好空间,记录一个cnt代表加入的数字个数,每次加入时,挨着往后进行单点更新即可
剩下的就是线段树板子题,单点修改 + 区间查询
-
代码
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/*
* @Author: NEFU AB-IN
* @Date: 2023-03-28 17:02:48
* @FilePath: \Acwing\1275\1275.cpp
* @LastEditTime: 2023-03-28 17:18:54
*/
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
struct sa
{
int l, r, mx;
} tr[N << 2];
void pushup(int p)
{
tr[p].mx = max(tr[ls].mx, tr[rs].mx);
}
void build(int p, int l, int r)
{
tr[p] = {l, r, 0};
if (l == r)
return;
int mid = l + r >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushup(p);
}
void update(int p, int L, int v)
{
if (tr[p].l == L && tr[p].r == L)
{
tr[p].mx = v;
return;
}
int mid = tr[p].l + tr[p].r >> 1;
if (L <= mid)
update(ls, L, v);
if (L > mid)
update(rs, L, v);
pushup(p);
}
int query(int p, int L, int R)
{
if (tr[p].l >= L && tr[p].r <= R)
{
return tr[p].mx;
}
int res = 0;
int mid = tr[p].l + tr[p].r >> 1;
if (L <= mid)
res = max(res, query(ls, L, R));
if (R > mid)
res = max(res, query(rs, L, R));
return res;
}
int m, p, cnt, a;
signed main()
{
IOS;
cin >> m >> p;
build(1, 1, m);
while (m--)
{
char op;
int t;
cin >> op >> t;
if (op == 'A')
{
update(1, ++cnt, (t + a) % p);
}
else
{
a = query(1, max(1LL, cnt - t + 1), cnt);
cout << a << '\n';
}
}
return 0;
}