CF600E Lomsat gelral
线段树合并。
考虑合并两颗线段树,设它们分别以
void merge(int &x, int y, int l, int r) {
if (!x) x = y;
else if (!y) return;
else if (l == r) {
tr[x].v.first += tr[y].v.first;
tr[x].v.second = l;
}
else {
int mid = l + r >> 1;
merge(tr[x].l, tr[y].l, l, mid);
merge(tr[x].r, tr[y].r, mid + 1, r);
pushup(x);
}
}void merge(int &x, int y, int l, int r) {
if (!x) x = y;
else if (!y) return;
else if (l == r) {
tr[x].v.first += tr[y].v.first;
tr[x].v.second = l;
}
else {
int mid = l + r >> 1;
merge(tr[x].l, tr[y].l, l, mid);
merge(tr[x].r, tr[y].r, mid + 1, r);
pushup(x);
}
}
merge(root[x], root[y], 1, N);
表示我们要把节点
动态开点保证了复杂度。
对于本题,我们在每个节点开一颗线段树,然后将所有儿子合并到父亲即可。