competitive-programing

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub Astral-23/competitive-programing

:heavy_check_mark: verify/Datastructure_undabledsu.test.cpp

Depends on

Code

#define PROBLEM "https://judge.yosupo.jp/problem/persistent_unionfind"
#include "../Utility/template.hpp"
#include "../Datastructure/undabledsu.hpp"



int main() {
    int N, Q;
    cin >> N >> Q;
    dsu o(N);
    vector<vector<vector<int>>> ivs(Q+1);

    rep(qi, 0, Q) {
        int t, k, u, v;
        cin >> t >> k >> u >> v;
        k++;
        ivs[k].push_back({t, int(qi)+1, u, v});
       
    }

    vector<int> ans(Q+1, -1);

    auto dfs = [&](auto f, int k, dsu& d) -> void {
        for(auto a : ivs[k]) {
            if(a[0] == 1) {
                if(d.same(a[2], a[3])) ans[a[1]-1] = 1;
                else ans[a[1]-1] = 0;
                continue;
            }
            else {
                d.merge(a[2], a[3]);
                f(f, a[1], d);
                d.undo();
            }
        }
    };


    dfs(dfs, 0, o);
    rep(qi,0 ,Q) if(ans[qi] != -1) cout << ans[qi] << '\n';
}
#line 1 "verify/Datastructure_undabledsu.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/persistent_unionfind"
#line 1 "Utility/template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (ll i = s; i < (ll)(t); i++)
#define rrep(i, s, t) for (ll i = (ll)(t) - 1; i >= (ll)(s); i--)
#define all(x) begin(x), end(x)

#define TT template <typename T>
TT using vec = vector<T>;
template <class T1, class T2> bool chmin(T1 &x, T2 y) {
    return x > y ? (x = y, true) : false;
}
template <class T1, class T2> bool chmax(T1 &x, T2 y) {
    return x < y ? (x = y, true) : false;
}
struct io_setup {
    io_setup() {
        ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        cout << fixed << setprecision(15);
    }
} io_setup;

/*
@brief verify用テンプレート
*/
#line 1 "Datastructure/undabledsu.hpp"
struct dsu {
    using vi = vector<int>;   
    using vvi = vec<vi>;
    struct dat {
        int u, v;
        ll x;
        dat(){}
        dat(int a, int b, ll c) : u(a), v(b), x(c) {}
    };
   
    vi par, sz, es;
    vec<ll> val;
    stack<dat> his;
    int cc;
   
    ll op(ll l, ll r) {return l + r;}
    ll inv(ll x) {return -x;}

    dsu(int n) {
        par = vi(n);
        sz = vi(n, 1);
        es = vi(n, 0);
        val = vec<ll>(n, 0);
        cc = n;
        iota(all(par), 0);
    }
  
    int leader(int u) {
        while(par[u] != u) {
            u = par[u];
        }
        return u;
    }
    
    bool same(int a, int b) {
        return leader(a) == leader(b);
    }
    
    bool merge(int a, int b) {
        a = leader(a), b = leader(b);
        if(sz[a] < sz[b]) swap(a, b);
        his.push(dat(a, b, val[a]));

        if(a == b) {
            es[a]++;
            return false;
        }
        else {
            cc--;
            par[b] = a;
            sz[a] += sz[b];
            es[a] += es[b] + 1;
            val[a] = op(val[a] , val[b]);
            return true;
        }
    }

    bool undo() {
        if(his.empty()) return false;
        dat p = his.top();
        auto [u, v, x] = p; 
        his.pop();
        par[v] = v;
        es[u]--;
        if(u != v) {
            cc++;
            sz[u] -= sz[v];
            es[u] -= es[v];
            val[u] = op(val[u], inv( val[v] ));
        }
        return true;
    }

    //以下、必要ないなら省く。

    void set(int v, ll f) {//注意: 代入では無い
        while(1) {
            val[v] = op(val[v], f);
            if(v == par[v]) break;
            v = par[v];
        }
    }

    ll get(int u) {
        return val[leader(u)];
    }

    int size(int u) {//uが含まれる連結成分のサイズを返す
        return sz[leader(u)];
    }

    int edgecnt(int u) {
        return es[leader(u)];
    }

    int component_count() {
        return cc;
    }

    vvi groups() {
        int n = par.size();
        vvi ms(n);
        rep(v, 0, n) {
            ms[leader(v)].push_back(v);
        }

        vvi res;
        rep(i, 0, n) if(ms[i].size() > 0) {
            res.push_back(ms[i]);
        }
        return res;
    }

};

/*
@brief undable dsu
@docs doc/undodsu.md
*/
#line 4 "verify/Datastructure_undabledsu.test.cpp"



int main() {
    int N, Q;
    cin >> N >> Q;
    dsu o(N);
    vector<vector<vector<int>>> ivs(Q+1);

    rep(qi, 0, Q) {
        int t, k, u, v;
        cin >> t >> k >> u >> v;
        k++;
        ivs[k].push_back({t, int(qi)+1, u, v});
       
    }

    vector<int> ans(Q+1, -1);

    auto dfs = [&](auto f, int k, dsu& d) -> void {
        for(auto a : ivs[k]) {
            if(a[0] == 1) {
                if(d.same(a[2], a[3])) ans[a[1]-1] = 1;
                else ans[a[1]-1] = 0;
                continue;
            }
            else {
                d.merge(a[2], a[3]);
                f(f, a[1], d);
                d.undo();
            }
        }
    };


    dfs(dfs, 0, o);
    rep(qi,0 ,Q) if(ans[qi] != -1) cout << ans[qi] << '\n';
}
Back to top page