P4137 Rmq Problem / mex

cxqghzj·2024-01-11 08:48·6 次阅读

P4137 Rmq Problem / mex

题意#

给定一个长度为 n 的数组。

q 次询问,每次询问区间 mex

Sol#

考虑主席树维护区间 mex

不难发现可以考虑维护当前所有点的最后出现的下标。

直接套板子即可。

Code#

Copy
#include <iostream> #include <algorithm> #include <cstdio> #include <array> using namespace std; #ifdef ONLINE_JUDGE #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++) char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf; #endif int read() { int p = 0, flg = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') flg = -1; c = getchar(); } while (c >= '0' && c <= '9') { p = p * 10 + c - '0'; c = getchar(); } return p * flg; } void write(int x) { if (x < 0) { x = -x; putchar('-'); } if (x > 9) { write(x / 10); } putchar(x % 10 + '0'); } const int N = 2e5 + 5; array <int, N> idx; namespace Sgt { array <int, N * 45> edge, lc, rc; int cnt; void modify(int &x, int l, int r, int y, int k) { cnt++; lc[cnt] = lc[x]; rc[cnt] = rc[x]; edge[cnt] = edge[x]; x = cnt; if (l == r) { edge[x] = k; return; } int mid = (l + r) >> 1; if (y <= mid) modify(lc[x], l, mid, y, k); else modify(rc[x], mid + 1, r, y, k); edge[x] = min(edge[lc[x]], edge[rc[x]]); } int query(int x, int l, int r, int k) { if (l == r) return l; int mid = (l + r) >> 1; if (edge[lc[x]] < k) return query(lc[x], l, mid, k); else return query(rc[x], mid + 1, r, k); } } array <int, N> rot; int main() { int n = read(), q = read(); idx.fill(-1); for (int i = 1; i <= n; i++) { int x = read(); rot[i] = rot[i - 1]; Sgt::modify(rot[i], 0, 2e5, x, i); idx[x] = i; } while (q--) { int l = read(), r = read(); write(Sgt::query(rot[r], 0, 2e5, l)), puts(""); } return 0; }
posted @   cxqghzj  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
目录