P2174 小Z的神奇数列

· · 题解

一篇通俗易懂的题解,小学知识即可。

提示

本做法需要卡常,如果要看稳定过的请移步其他题解。

分析

首先这一看就是个数据结构题,我们整理一下这个数据结构的需求:

我们一个操作一个操作来攻克。

PS:下文操作名用打印机字体表示。

\texttt{D x} 操作

请不要以为一行 erase(x) 就可以搞定了,因为那个操作会把所有等于 x 的值清空,所以,我们要用到这个操作:

erase(pos)

其中 pos 是一个迭代器,上述代码的意思就是删除 pos 处的位置,我们可以用 lower_bound 找到 x 的位置后删除那个位置上的值,代码如下。

x = read();
auto pos = st.lower_bound(x);
st.erase(pos);
// st 为 multiset 的名字,下同

\texttt{B} 操作

这个简单,几句话即可。

auto p = st.end();
p--;  // end() 返回的是尾部的后一个位置,所以要 p--
write(*p);
putchar('\n');

\texttt{S} 操作

```cpp auto p = st.begin(); write(*p); putchar('\n'); ``` #### $\texttt{M}$ 操作 快速幂即可,不会的[右转出门](https://www.luogu.com.cn/problem/solution/P1226)。 ```cpp // 省略快速幂 auto p = st.end(); p--; write(qpow(*p, *st.begin())); putchar('\n'); ``` #### $\texttt{T}$ 操作 直接求?复杂度到天上去。 在输入时预处理所有数的乘积(默认已经取模过),当出现 $\texttt{D x}$ 操作时就除以 $x$。 代码比较分散,直接看总代码里的吧。 ### Code ```cpp #include <bits/stdc++.h> using namespace std; #define endl '\n' #define pair pair<int, int> #define int long long // char buf[1 << 20], *_now = buf, *_end = buf; // #define getchar() (_now == _end && (_end = (_now = buf) + fread(buf, 1, 1 << // 20, stdin), _now == _end) ? EOF : *_now++) int n, q, x; long long pd = 1; char opt; multiset<int> st; inline int read() { int p = 0; char c = getchar(); for (; c < '0' || c > '9'; c = getchar()); for (; c >= '0' && c <= '9'; p = (p << 3) + (p << 1) + (c ^ 48), c = getchar()); return p; } void write(long long t) { if (t < 0) putchar('-'), t = -t; if (t > 9) write(t / 10); putchar(t % 10 + '0'); return; } long long qpow(long long a, long long b) { long long res = 1; while (b) { if (b & 1) res = res * a % 317847191; a = a * a % 317847191; b >>= 1; } return res; } signed main() { n = read(), q = read(); for (int i = 1; i <= n; i++) x = read(), st.insert(x), pd = pd * (x % 317847191) % 317847191; // 预处理乘积 while (q--) { scanf(" %c", &opt); // 如果写成 %c 会把换行符读进去 if (opt == 'D') { x = read(); auto pos = st.lower_bound(x); st.erase(pos); pd /= x; // 删掉就除以 x } else if (opt == 'B') { auto p = st.end(); p--; write(*p); putchar('\n'); } else if (opt == 'S') { auto p = st.begin(); write(*p); putchar('\n'); } else if (opt == 'M') { auto p = st.end(); p--; write(qpow(*p, *st.begin())); putchar('\n'); } else if (opt == 'T') { write(pd % 317847191); putchar('\n'); } } return 0; } ```