可持久化大家族
我花了很久时间终于明白我写不出h并不是因为我代码能力不行而是我不会主席树也不会线段树合并。
- 静态主席树
[POI]2014 KUR-Couriers(https://www.luogu.org/problemnew/show/3567)
code
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int, int>
const int N = 2e5 * 60, XN = 310;
int a[N], n, m, b[N], rt[N];
struct segtree{
int ls[N], rs[N], val[N], tot;
void init() {
tot = 0;
memset(ls, 0, sizeof(ls));
memset(rs, 0, sizeof(rs));
memset(val, 0, sizeof(val));
memset(rt, 0, sizeof(rt));
}
int newnode(int x = 0) {
ls[++tot] = ls[x], rs[tot] = rs[x], val[tot] = val[x];
return tot;
}
int upd(int x, int l, int r, int q) {
x = newnode(x);
val[x] += 1;
if (l == r) {
return x;
}
int mid = (l + r) / 2;
if (q <= mid) ls[x] = upd(ls[x], l, mid, q);
else rs[x] = upd(rs[x], mid + 1, r, q);
return x;
}
int que(int x, int y, int l, int r, int k) {
if (l == r) return l;
int mid = (l + r) / 2;
int tmp = val[ls[y]] - val[ls[x]];
if (tmp > k) return que(ls[x], ls[y], l, mid, k);
tmp = val[rs[y]] - val[rs[x]];
if (tmp > k) return que(rs[x], rs[y], mid + 1, r, k);
return 0;
}
int build(int l, int r) {
int x = ++tot;
if (l == r) return tot;
int mid = (l + r) / 2;
ls[x] = build(l, mid);
rs[x] = build(mid + 1, r);
return x;
}
}sgt;
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
b[i] = a[i];
}
sort(b + 1, b + n + 1);
int len = unique(b + 1, b + n + 1) - b - 1;
sgt.init();
rt[0] = sgt.build(1, len);
for (int i = 1; i <= n; i++) {
rt[i] = sgt.upd(rt[i - 1], 1, len, lower_bound(b + 1, b + len + 1, a[i]) - b);
}
while(m--) {
int l, r, k; cin >> l >> r;
cout << b[sgt.que(rt[l - 1], rt[r], 1, len, (r - l + 1) / 2)] << endl;
}
}
- 动态主席树
- 可持久化并查集

浙公网安备 33010602011771号