[洛谷P2174]小Z的神奇数列
题目大意:有$n(n\leqslant10^6)$个数,$5$种操作:
- $D\;x:$从数列中删除$x$,相同的数只删除一个
- $B:$最大值
- $S:$最小值
- $M:$输出$max^{min}\pmod{317847191}$
- $T:$输出乘积模$317847191$
题解:堆,没有插入,可以离线倒着搞,把删除变成插入即可
题解:卡$map$
C++ Code:
#include <cstdio> #include <algorithm> #include <map> #include <vector> #include <queue> #include <cctype> namespace R { int x, ch; inline int read() { ch = getchar(); while (isspace(ch)) ch = getchar(); for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15); return x; } } using R::read; #define maxn 1000010 const int mod = 317847191; inline int pw(int base, int p) { int res = 1; for (; p; p >>= 1, base = static_cast<long long> (base) * base % mod) if (p & 1) res = static_cast<long long> (res) * base % mod; return res; } int n, m; long long prod = 1; int s[maxn], c[maxn]; int ans[maxn]; int ret[maxn], num[maxn], cnt[maxn]; char op[maxn]; std::priority_queue<int> Max; std::priority_queue<int, std::vector<int>, std::greater<int> > Min; int main() { n = read(), m = read(); for (int i = 1; i <= n; i++) s[i] = read(); std::sort(s + 1, s + n + 1); for (int i = 1, x; i <= n; i++) { if (s[i] != s[i - 1]) x = i; else x = num[i - 1]; num[i] = x; ret[x] = s[i]; } for (int i = 1; i <= m; i++) { scanf("%1s", op + i); if (op[i] == 'D') c[i] = read(), cnt[std::lower_bound(s + 1, s + n + 1, c[i]) - s]++; } for (int i = 1; i <= n; i++) if (!cnt[num[i]]) { Max.push(s[i]); Min.push(s[i]); prod = prod * s[i] % mod; } else cnt[num[i]]--; for (int i = m; i; i--) { switch (op[i]) { case 'D': { Max.push(c[i]); Min.push(c[i]); prod = prod * c[i] % mod; break; } case 'B': ans[i] = Max.top(); break; case 'S': ans[i] = Min.top(); break; case 'M': ans[i] = pw(Max.top(), Min.top()); break; case 'T': ans[i] = prod; } } for (int i = 1; i <= m; i++) if (op[i] != 'D') printf("%d\n", ans[i]); return 0; }