2019 cow farm off the eighth multi-school E_Explorer revocable disjoint-set (stack) + segment tree

@ (More than 2019 cattle off summer school camp (Session 8) E_Explorer)

Meaning of the questions:

link

Title Similarly: CF366D, Gym101652T
this question you \ (n (100000) \) points \ (m (10000) \) edges, each undirected edges allows numbered \ ([Li, Ri] ( 1 \ le Li \ le Ri \) \) le 1e9 people in and asked from \ (1 \) to \ (n \) how many people pass.


analysis:

Lv 30 multiple race violence to no avail. . .
Because the scope of the original data is done before a title 1000, when the practice seems to be the discrete interval enumeration violence run \ (dfs \) queries or run with a range of violent \ (BFS \) last check again. . .

Shed tears of chicken dishes, mainly limited thinking, and this is very deadly.
I heard that this problem can be LCT write now will be revoked and check the wording set + segment tree. .
Here Insert Picture Description

  • Mentioned above is also very clear, all the weights discrete moment, and then build a keyword is to the right of the tree line
  • Let's also mention that this segment tree and a cow on exactly the same question off of E, left and right to open and close tree line, that is, each leaf node represents some weight range. This interpretation of the tree line: here Wallpaper
  • Then each node of the tree segments stored to cover all sides of the current weight range point.
  • After completion of the update interval, the whole teeth tree walking again answer.
  • For the edge included in the leaf node to the root of this weight interval, with a disjoint-set to maintain connectivity.
  • To backtrack a few side effects of the revocation of the above. The combined record it on two sides of a root, and then restore them \ (fa [], rnk [ ] \) on the line.
  • With a stack edge can record added, LIFO operation of the present structure is suitable revocation question. Also, revocable disjoint-set path can not be compressed, it must be merged by rank.

Code

const int MXN = 3e3 + 7;
const int MXE = 2e6 + 7;
int n, m;
vector<int> sum[MXN<<2], vs;
int fa[MXN], rnk[MXN], top;
struct lh {
    int fi, se, u, v;
}stak[MXN];
struct lp {
    int u, v, l ,r;
}cw[MXN];
void update(int L, int R, int v, int l ,int r, int rt) {
    if(L <= l && r <= R) {
        sum[rt].eb(v);
        return;
    }
    int mid = (l + r) >> 1;
    if(L > mid) update(L, R, v, mid + 1, r, rt<<1|1);
    else if(R <= mid) update(L, R, v, l, mid, rt<<1);
    else {
        update(L, mid, v, l, mid, rt<<1), update(mid + 1, R, v, mid + 1, r, rt<<1|1);
    }
}
int Fi(int x) {
    return fa[x] == x? x: Fi(fa[x]);
}
int pa, pb, ans;
void build(int l, int r, int rt) {
    if(l == r) {
//        debug(l, r, Fi(3), Fi(5))
        for(auto x: sum[rt]) {
            pa = Fi(cw[x].u), pb = Fi(cw[x].v);
            if(pa == pb) continue;
//            debug(l, r, cw[x].u, cw[x].v)
            if(rnk[pa] > rnk[pb]) swap(pa, pb);
            fa[pa] = pb;
            rnk[pb] += rnk[pa];
            stak[++ top] = {rt, x, pa, pb};
        }
        if(Fi(1) == Fi(n)) ans += vs[l+1] - vs[l];
        while(top && stak[top].fi == rt) {//撤销
            int x = stak[top].se;
            if(rnk[stak[top].u] > rnk[stak[top].v]) {
                fa[stak[top].v] = stak[top].v;
                rnk[stak[top].u] -= rnk[stak[top].v];
            }else {
                fa[stak[top].u] = stak[top].u;
                rnk[stak[top].v] -= rnk[stak[top].u];
            }
            -- top;
        }
//        debug(l, r, Fi(3), Fi(5))
        return;
    }
    int mid = (l + r) >> 1;
//    debug(l, r, mid, rt)
    for(auto x: sum[rt]) {
        pa = Fi(cw[x].u), pb = Fi(cw[x].v);
        if(pa == pb) continue;
//        debug(pa, pb)
        if(rnk[pa] > rnk[pb]) swap(pa, pb);
        fa[pa] = pb;
        rnk[pb] += rnk[pa];
        stak[++ top] = {rt, x, pa, pb};
    }
    build(l, mid, rt << 1), build(mid + 1, r, rt << 1 | 1);
    while(top && stak[top].fi == rt) {//撤销
        int x = stak[top].se;
        if(rnk[stak[top].u] > rnk[stak[top].v]) {
            fa[stak[top].v] = stak[top].v;
            rnk[stak[top].u] -= rnk[stak[top].v];
        }else {
            fa[stak[top].u] = stak[top].u;
            rnk[stak[top].v] -= rnk[stak[top].u];
        }
        -- top;
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("/home/cwolf9/CLionProjects/ccc/in.txt", "r", stdin);
//    freopen("/home/cwolf9/CLionProjects/ccc/out.txt", "w", stdout);
#endif
    n = read(), m = read();
    for(int i = 1; i <= n; ++i) fa[i] = i, rnk[i] = 1;
    vs.eb(0);
    for(int i = 1; i <= m; ++i) {
        cw[i].u =read(), cw[i].v = read();cw[i].l = read(), cw[i].r = read();
        vs.eb(cw[i].l), vs.eb(cw[i].r + 1);
    }
    my_unique(vs);
//    for(auto x: vs) printf("%d ", x); printf("\n");
    for(int i = 1; i <= m; ++i) {
        update(lower_bound(all(vs), cw[i].l) - vs.begin(), upper_bound(all(vs), cw[i].r) - vs.begin() - 1, i, 1, vs.size() - 1, 1);
//        debug(lower_bound(all(vs), cw[i].l) - vs.begin(), upper_bound(all(vs), cw[i].r) - vs.begin() - 1, cw[i].u, cw[i].v);
    }
    build(1, vs.size() - 1, 1);
    printf("%d\n", ans);
    return 0;
}

Two to be completed exercises: CF 813F revocable disjoint-set + partition , BZOJ 3237 partition of the CDQ + with revocation of disjoint-set
review Weighted disjoint-set and persistence disjoint-set.

Guess you like

Origin www.cnblogs.com/Cwolf9/p/11334108.html