【题目链接】
【思路要点】
- 动态开点,树套树。
- 时间复杂度 O ( M L o g 2 N ) O(MLog^2N) O(MLog2N) 。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 100005 #define MAXP 10000005 template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } struct SegmentTree { struct Node { int lc, rc; int value; } a[MAXP]; int root, size, n; int Ql, Qr, D; void build(int &root, int l, int r) { root = ++size; if (l == r) return; int mid = (l + r) / 2; build(a[root].lc, l, mid); build(a[root].rc, mid + 1, r); } void init(int x) { n = x; root = size = 0; build(root, 1, n); } void chkmax(int &x, int y) { x = max(x, y); } void ModifyB(int &root, int l, int r, int ql, int qr, int d) { if (root == 0) root = ++size; if (l == ql && r == qr) { chkmax(a[root].value, d); return; } int mid = (l + r) / 2; if (mid >= ql) ModifyB(a[root].lc, l, mid, ql, min(mid, qr), d); if (mid + 1 <= qr) ModifyB(a[root].rc, mid + 1, r, max(mid + 1, ql), qr, d); } void ModifyA(int root, int l, int r, int ql, int qr) { if (l == ql && r == qr) { ModifyB(a[root].value, 1, n, Ql, Qr, D); return; } int mid = (l + r) / 2; if (mid >= ql) ModifyA(a[root].lc, l, mid, ql, min(mid, qr)); if (mid + 1 <= qr) ModifyA(a[root].rc, mid + 1, r, max(mid + 1, ql), qr); } void modify(int l, int r, int ql, int qr, int d) { Ql = ql, Qr = qr, D = d; ModifyA(root, 1, n, l, r); } int QueryB(int root, int l, int r, int pos) { if (root == 0) return 0; if (l == r) return a[root].value; int ans = a[root].value, mid = (l + r) / 2; if (mid >= pos) chkmax(ans, QueryB(a[root].lc, l, mid, pos)); else chkmax(ans, QueryB(a[root].rc, mid + 1, r, pos)); return ans; } int QueryA(int root, int l, int r, int pos, int x) { if (l == r) return QueryB(a[root].value, 1, n, x); int ans = QueryB(a[root].value, 1, n, x), mid = (l + r) / 2; if (mid >= pos) chkmax(ans, QueryA(a[root].lc, l, mid, pos, x)); else chkmax(ans, QueryA(a[root].rc, mid + 1, r, pos, x)); return ans; } int query(int x, int y) { return QueryA(root, 1, n, x, y); } } SMT; int n, m, value[MAXN]; vector <int> a[MAXN]; int main() { read(n), read(m); SMT.init(n); for (int i = 1; i <= n; i++) { read(value[i]); a[value[i]].push_back(i); } for (int i = 1; i <= n; i++) { for (unsigned j = 0; j < a[i].size(); j++) { int l, r, mid = a[i][j]; if (j == 0) l = 1; else l = a[i][j - 1] + 1; if (j == a[i].size() - 1) r = n; else r = a[i][j + 1] - 1; SMT.modify(l, mid, mid, r, i); } } int lastans = 0; for (int i = 1; i <= m; i++) { int l, r; read(l), read(r); l = (l + lastans) % n + 1; r = (r + lastans) % n + 1; if (l > r) swap(l, r); printf("%d\n", lastans = SMT.query(l, r)); } return 0; }