1 条题解
-
0
这是可持久化线段树模板题,粘贴模板即可。
#include <bits/stdc++.h> using namespace std; namespace INPUT_SPACE { const int S = 1 << 25; char B[S]; char* H; char* T; inline char gc() { if (H == T) { H = B; T = B + fread(B, 1, S, stdin); } if (H == T) return 0; char* I = H; H++; return *I; } inline unsigned int inn() { unsigned int x = 0; char c; c = gc(); while (c < '0') c = gc(); while (c >= '0') { x *= 10; x += c - '0'; c = gc(); } return x; } }; using INPUT_SPACE::inn; const int PTD = 30; struct V { int a; int ll; int rr; int l; int r; }; struct U { V v[8000012]; int roots[200012]; int ts; int st; void init(int n) { ts = n; st = n; for (int i = 1; i <= n; i++) v[i].rr = (1 << PTD) - 1; for (int i = 1; i <= n; i++) roots[i] = i; } void expand(int b) { if (v[b].ll == v[b].rr) return; if (v[b].l == 0) { ts++; v[ts] = (V){0, v[b].ll, (v[b].ll + v[b].rr) >> 1, 0, 0}; v[b].l = ts; } if (v[b].r == 0) { ts++; v[ts] = (V){0, ((v[b].ll + v[b].rr) >> 1) + 1, v[b].rr, 0, 0}; v[b].r = ts; } } bool create(int x, int b) { if (v[b].ll == x && v[b].rr == x) return true; expand(b); int lmid = (v[b].ll + v[b].rr) >> 1, rmid = lmid + 1; if (x <= lmid) return create(x, v[b].l); if (x >= rmid) return create(x, v[b].r); } bool add(int x, int y, int b, int c) { v[b].a += v[c].a + y; if (v[b].ll == x && v[b].rr == x) return true; int lmid = (v[b].ll + v[b].rr) >> 1, rmid = lmid + 1; if (x <= lmid) v[b].r = v[c].r; if (x >= rmid) v[b].l = v[c].l; expand(b); if (x <= lmid) return add(x, y, v[b].l, v[c].l); if (x >= rmid) return add(x, y, v[b].r, v[c].r); } int get(int l, int r, int b) { if (!b) return 0; if (l == v[b].ll && r == v[b].rr) return v[b].a; int lmid = (v[b].ll + v[b].rr) >> 1, rmid = lmid + 1; if (r <= lmid) return get(l, r, v[b].l); if (l >= rmid) return get(l, r, v[b].r); return get(l, lmid, v[b].l) + get(rmid, r, v[b].r); } }; U t; int a[200012]; int main() { int n = inn(), m = inn(); t.init(n + 1); for (int i = 1; i <= n; i++) { a[i] = inn(); t.create(a[i], t.roots[n + 1]); } t.roots[0] = t.roots[n + 1]; for (int i = 1; i <= n; i++) t.add(a[i], 1, t.roots[i], t.roots[i - 1]); for (int i = 1; i <= m; i++) { int l = inn(), r = inn(), k = inn(); int ll = 0, rr = 1073741823; while (ll < rr) { int mid = (0ll + ll + rr) / 2; int x = t.get(0, mid, t.roots[r]); int y = t.get(0, mid, t.roots[l - 1]); if (x - y >= k) rr = mid; else ll = mid + 1; } int a1 = t.get(0, ll, t.roots[r]) - t.get(0, ll, t.roots[l - 1]); int a2 = t.get(0, ll - 1, t.roots[r]) - t.get(0, ll - 1, t.roots[l - 1]); cout << a1 - a2 << endl; } return 0; }
- 1
信息
- ID
- 64
- 时间
- 3000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 20
- 已通过
- 3
- 上传者