BZOJ 4025: bipartite FIG.

4025: bipartite graph
idea:
Consider the partition of time, and then each side by adding the appropriate influence time interval (similar partition tree). Then consider each leaf node comprising edges connected together, and determines there is no strange ring.
Merge operation because of the need to withdraw some disjoint-set during the partition, so you need to use revocable disjoint-set. Since then sentenced to ring, so they need to maintain the distance to each point to the parent node \ (dp [i] \) ,
so it is necessary to use a weighted disjoint-set.
Code:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head
 
const int N = 1e5 + 5;
int n, m, T, u, v, l, r;
vector<pii> vc[N<<2];
bool ans[N];
struct UFS {
    stack<pair<int*, int> > stk;
    int fa[N], rnk[N], dp[N], c;
    inline void init(int n) {
        for (int i = 0; i <= n; ++i) fa[i] = i, rnk[i] = 0, dp[i] = 0;
        c = 0;
    }
    inline int Find(int x) {
        while(x^fa[x]) x = fa[x];
        return x;
    }
    inline int Deep(int x) {
        int res = 0;
        while(x^fa[x]) res += dp[x], x = fa[x];
        return res;
    }
    inline void Merge(int x, int y) {
        int fx = Find(x), fy = Find(y);
        if(fx == fy) {
            int dx = Deep(x), dy = Deep(y);
            if((dx+dy+1)%2) {
                stk.push(mp(&c, c));
                c++;
            }
            return ;
        }
        if(rnk[fx] <= rnk[fy]) {
            stk.push(mp(fa+fx, fa[fx]));
            stk.push(mp(dp+fx, dp[fx]));
            dp[fx] = dp[y]-dp[x]+1;
            fa[fx] = fy;
            if(rnk[fx] == rnk[fy]) {
                stk.push(mp(rnk+fy, rnk[fy]));
                rnk[fy]++;
            }
        }
        else {
            stk.push(mp(fa+fy, fa[fy]));
            stk.push(mp(dp+fy, dp[fy]));
            dp[fy] = dp[x]-dp[y]+1;
            fa[fy] = fx;
        }
    }
    inline void Undo() {
        *stk.top().fi = stk.top().se;
        stk.pop();
    }
}ufs;
void update(int L, int R, pii p, int rt, int l, int r) {
    if(L <= l && r <= R) return vc[rt].pb(p), void();
    int m = (l+r) >> 1;
    if(L <= m)update(L, R, p, ls);
    if(R > m) update(L, R, p, rs);
}
void dfs(int rt, int l, int r) {
    for (int i = 0; i < vc[rt].size();++i) ufs.Merge(vc[rt][i].fi, vc[rt][i].se);
    if(l == r) {
        if(ufs.c) printf("No\n");
        else printf("Yes\n");
        return ;
    }
    int sz = ufs.stk.size();
    int m = (l+r) >> 1;
    dfs(ls);
    while(ufs.stk.size() > sz) ufs.Undo();
    dfs(rs);
    while(ufs.stk.size() > sz) ufs.Undo();
}
int main() {
    scanf("%d %d %d", &n, &m, &T);
    for (int i = 1; i <= m; ++i) scanf("%d %d %d %d", &u, &v, &l, &r), update(l+1, r, {u, v}, 1, 1, T);
    ufs.init(n);
    dfs(1, 1, T);
    return 0;
}

Guess you like

Origin www.cnblogs.com/widsom/p/11335239.html