Explorer (2019 Nian cattle off more school eighth field E + title + segment tree revocable disjoint-set)

Topic Link

Portal

The meaning of problems

Give you an undirected graph, each edge \ (u_i, v_i \) weights in the range of \ ([L_i, R_i] \) , to go through this edge condition that you want capacity \ ([L_i , R_i] \) , you now have to ask you how many kinds of capacity so that you can get from \ (1 \) went \ (the n-\) .

Thinking

Followed bigwigs code learn wave revocable disjoint-set and show operating segment tree, feel good food ah.

First, we use disjoint-set to maintain the inner side of the corresponding weight range of values which the segment tree node zone, with \ (vector \) be able to save the node number (Note that since the interval is too large we need to build discrete left close right open segment tree). Query time all the way down through the node number stored corresponding to the endpoints of all edges with two disjoint-set to maintain connectivity when the line reaches the node on the leaves contain the description of all the leaf nodes corresponding to section edges are maintained with disjoint-set, then re-determined \ (1 \) and \ (n-\) is in communication with a block which, in this section will be a length which is added to the answer, not to illustrate the junction corresponding to the point such that the section can not be \ (1 \) come \ (n-\) , combined operations before backtracking set time of withdrawal disjoint-set.

Code

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;

#define lson (rt<<1),L,mid
#define rson (rt<<1|1),mid + 1,R
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)

const double eps = 1e-8;
const int mod = 1000000007;
const int maxn = 200000 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;

pii st[maxn*4];
int n, m, tot, tp, ans;
vector<int> vec[maxn*4];
int u[maxn], v[maxn], L[maxn], R[maxn];
int num[maxn*2], fa[maxn], sz[maxn];

int fi(int x) {
    return fa[x] == x ? x : fi(fa[x]);
}

void merge(int u, int v) {
    int x = fi(u), y = fi(v);
    if(x == y) {
        st[++tp] = {-1, -1};  //按照我的写法不能省略,因为我是根据结点对应的vector的size来撤消的,少了这个那么tp会减到负数导致re。
        return;
    }
    if(sz[x] < sz[y]) swap(x, y);
    sz[x] += sz[y];
    fa[y] = x;
    st[++tp] = {x, y};
}

void cancel() {
    int x = st[tp].first;
    int y = st[tp--].second;
    if(x == -1) return;
    sz[x] -= sz[y];
    fa[y] = y;
}

void update(int l, int r, int id, int rt, int L, int R) {
    if(l <= L && R <= r) {
        vec[rt].emplace_back(id);
        return;
    }
    int mid = (L + R) >> 1;
    if(r <= mid) update(l, r, id, lson);
    else if(l > mid) update(l, r, id, rson);
    else {
        update(l, mid, id, lson);
        update(mid + 1, r, id, rson);
    }
}

void query(int l, int r, int rt) {
    for(int i = 0; i < (int)vec[rt].size(); ++i) {
        int id = vec[rt][i];
        merge(u[id], v[id]);
    }
    if(l == r) {
        int x = fi(1), y = fi(n);
        if(x == y) {
            ans += num[r+1] - num[l];
        }
        for(int i = 0; i < (int)vec[rt].size(); ++i) {
            cancel();
        }
        return;
    }
    int mid = (l + r) >> 1;
    query(l, mid, rt<<1);
    query(mid + 1, r, rt<<1|1);
    for(int i = 0; i < (int)vec[rt].size(); ++i) {
        cancel();
    }
}

int main() {
#ifndef ONLINE_JUDGE
    FIN;
#endif
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; ++i) {
        scanf("%d%d%d%d", &u[i], &v[i], &L[i], &R[i]);
        num[++tot] = L[i];
        num[++tot] = R[i] + 1;
    }
    sort(num + 1, num + tot + 1);
    tot = unique(num + 1, num + tot + 1) - num - 1;
    for(int i = 1; i <= m; ++i) {
        int l = lower_bound(num + 1, num + tot + 1, L[i]) - num;
        int r = lower_bound(num + 1, num + tot + 1, R[i] + 1) - num;
        update(l, r - 1, i, 1, 1, tot);
    }
    for(int i = 1; i <= n; ++i) fa[i] = i, sz[i] = 1;
    query(1, tot, 1);
    printf("%d\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/Dillonh/p/11334020.html