线段树合并的小方法
线段树合并
1、例题:P3324
struct node{
int siz, id, l, r;
node(int siz = 0, int id = 0, int l = 0, int r = 0) : siz(siz), id(id), l(l), r(r) {}
} tree[N + 1];
int tot;
int rt[N + 1];
void push_up(int root) {
auto &ls = tree[root].l, &rs = tree[root].r;
tree[root].siz = tree[ls].siz + tree[rs].siz;
}
void ins(int &nw, int l, int r, int pos, int id) {
int mid = l + r >> 1;
nw = ++tot;
if (l == r) {
tree[nw].siz = 1;
tree[nw].id = id;
return;
}
if (pos <= mid) ins(tree[nw].l, l, mid, pos, id);
else ins(tree[nw].r, mid + 1, r, pos, id);
push_up(nw);
}
int mer(int l, int r, int x, int y) {// 线段树合并
if (!x || !y) {
return (x | y);
}
if (l == r) {
tree[x].siz += tree[y].siz;
return x;
}
int mid = l + r >> 1;
tree[x].l = mer(l, mid, tree[x].l, tree[y].l);
tree[x].r = mer(mid + 1, r, tree[x].r, tree[y].r);
push_up(x);
return x;
}
int ask(int nw, int l, int r, int k) {
int mid = l + r >> 1;
auto &ls = tree[nw].l, &rs = tree[nw].r;
if (l == r) {
return (!tree[nw].id ? -1 : tree[nw].id);
}
if (tree[ls].siz >= k) {
return ask(ls, l, mid, k);
} else {
return ask(rs, mid + 1, r, k - tree[ls].siz);
}
}
struct DSU{
int n, cnt;
vector<int> fa, siz;
DSU() {}
DSU(int n_) : fa(n_ + 1), siz(n_ + 1, 1) {
n = n_;
cnt = n;
iota(fa.begin(), fa.end(), 0);
}
inline void init() {
}
inline int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
inline bool ral(int x, int y) {
return find(x) == find(y);
}
inline bool mergy(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return false;
if (siz[fx] > siz[fy]) swap(fx, fy);
cnt--;
fa[fx] = fy;
mer(1, n, rt[fy], rt[fx]);
siz[fy] += siz[fx];
return true;
}
};
void solve() {
int n, m, q;
cin >> n >> m;
DSU dsu(n);
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
ins(rt[i], 1, n, x, i);
}
for (int i = 1, u, v; i <= m; i++) {
cin >> u >> v;
dsu.mergy(u, v);
}
cin >> q;
for (int i = 1; i <= q; i++) {
char c;
cin >> c;
if (c == 'Q') {
int x, y;
cin >> x >> y;
x = dsu.find(x);
cout << ask(rt[x], 1, n, y) << '\n';
} else {
int x, y;
cin >> x >> y;
x = dsu.find(x);
y = dsu.find(y);
dsu.mergy(x, y);
}
}
}

浙公网安备 33010602011771号