• Codeforces 813F Bipartite Checking 线段树 + 并查集


    Bipartite Checking

    感觉这种题写过很多次啦。 删边很难操作, 我们把边的影响区间丢到线段树上, 就全部变成加边了。

    我们用按秩合并并查集维护每个点到根的奇偶性, 合并的时候能在小的子树的根打个标记。

    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}
    
    int n, q;
    int x[N], y[N];
    int fa[N], sz[N], mask[N];
    bool ans[N];
    vector<pair<PII, int> > event;
    
    int getRoot(int x) {
        return fa[x] == x ? x : getRoot(fa[x]);
    }
    
    int getMask(int x, int ans) {
        ans ^= mask[x];
        if(x == fa[x]) return ans;
        return getMask(fa[x], ans);
    }
    
    void rollBack() {
        int x = event.back().fi.fi;
        int y = event.back().fi.se;
        int z = event.back().se;
        event.pop_back();
        if(x == -1) return;
        sz[x] -= sz[y];
        fa[y] = y;
        mask[y] ^= z;
    }
    
    map<PII, int> E;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    
    vector<PII> Tree[N << 2];
    
    void update(int L, int R, PII edge, int l, int r, int rt) {
        if(R < l || r < L || R < L) return;
        if(L <= l && r <= R) {
            Tree[rt].push_back(edge);
            return;
        }
        int mid = l + r >> 1;
        update(L, R, edge, lson);
        update(L, R, edge, rson);
    }
    
    void solve(bool can, int l, int r, int rt) {
        for(auto& e : Tree[rt]) {
            int u = e.fi, v = e.se;
            int x = getRoot(u);
            int y = getRoot(v);
            if(sz[x] < sz[y]) swap(x, y), swap(u, v);
            if(x == y) {
                int utox = getMask(u, 0);
                int vtoy = getMask(v, 0);
                if(!(utox ^ vtoy)) can = false;
                event.push_back(mk(mk(-1, -1), -1));
            } else {
                int utox = getMask(u, 0);
                int vtoy = getMask(v, 0);
                sz[x] += sz[y];
                mask[y] ^= (utox ^ vtoy ^ 1);
                fa[y] = x;
                event.push_back(mk(mk(x, y), (utox ^ vtoy ^ 1)));
            }
        }
        if(l == r) {
            ans[l] = can;
            for(auto& e : Tree[rt]) rollBack();
            return;
        }
        int mid = l + r >> 1;
        solve(can, lson);
        solve(can, rson);
        for(auto& e : Tree[rt]) rollBack();
    }
    
    int main() {
        for(int i = 1; i < N; i++) fa[i] = i, sz[i] = 1;
        scanf("%d%d", &n, &q);
        for(int i = 1; i <= q; i++) {
            int x, y; scanf("%d%d", &x, &y);
            if(x > y) swap(x, y);
            if(E.find(mk(x, y)) != E.end()) {
                update(E[mk(x, y)], i - 1, mk(x, y), 1, q, 1);
                E.erase(mk(x, y));
            } else {
                E[mk(x, y)] = i;
            }
        }
        for(auto& e : E) update(e.se, q, e.fi, 1, q, 1);
        E.clear();
        solve(1, 1, q, 1);
        for(int i = 1; i <= q; i++) puts(ans[i] ? "YES" : "NO");
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    消息中间件
    线程以及多线程
    锁以及分布式锁
    并发以及高并发
    SpringBoot + SpringCloud学习踩坑实记
    公众号笔记: 2018年12月
    浅谈final关键字的用法
    浅谈static关键字的四种用法
    Linux常用的一些命令
    HTTPS
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10905953.html
Copyright © 2020-2023  润新知