CSES Dynamic Connectivity
// compile: make data
// run: time ./data < data.in > data.out
#include <bits/stdc++.h>
using namespace std;
// #pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
std::ifstream terminal("/dev/tty");
#define PP cerr<<"\033[1;30mpause...\e[0m",terminal.ignore();
#else
#define debug(x...)
#define Debug(x...)
#define PP
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x),__VA_ARGS__})
#define cmax(x,...) x=max({(x),__VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
// #define INF (int)(1152921504606846976)
#define INF (int)(0x3f3f3f3f)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
// #define int long long
#define uint unsigned long long
#define MAXN 200010

struct lct {
    struct node {
        node *ch[2], *parent;
        int inv, minv, minp, val;
    };
    vector<node> vertex;
    vector<vector<int>> ch;
    int n;
    lct(int N) {vertex.resize(n = N); }
    int ind(node *x) {return x - &vertex[0]; }
    int isroot(node *x) {return x->parent ? (x->parent->ch[0] != x && x->parent->ch[1] != x) : 1; }
    void pushdown(node *x){
        if (x->inv) {
            if (x->ch[0]) x->ch[0]->inv ^= 1;
            if (x->ch[1]) x->ch[1]->inv ^= 1;
            swap(x->ch[0], x->ch[1]);
            x->inv = 0;
        }
    }
    void pushup(node *x) {
        int lc = x->ch[0] ? x->ch[0]->minv : INF;
        int rc = x->ch[1] ? x->ch[1]->minv : INF;
        x->minv = x->val, x->minp = ind(x);
        if (lc < x->minv) x->minv = lc, x->minp = x->ch[0]->minp;
        if (rc < x->minv) x->minv = rc, x->minp = x->ch[1]->minp;
    }
    void rotate(node *x) {
        node *y = x->parent, *z = y->parent;
        int t = y->ch[1] == x;
        if (!isroot(y)) z->ch[z->ch[1]==y] = x;
        y->ch[t] = x->ch[!t];
        if (x->ch[!t]) x->ch[!t]->parent = y;
        x->ch[!t] = y, y->parent = x, x->parent = z;
        pushup(y);
    }
    void splay(node *x) {
        stack<node*> st; st.push(x);
        for (node *i = x; !isroot(i); i = i->parent) st.push(i->parent);
        while (!st.empty()) pushdown(st.top()), st.pop();
        for (node *y = x->parent; y && !isroot(x); y = x->parent) {
            if (!isroot(y)) rotate(((y->parent->ch[0]==y) ^ (y->parent->ch[0]==x)) ? x : y);
            rotate(x);
        }
        pushup(x);
    }
    node *access(node *x){
        node *t = nullptr;
        for (; x; t = x, x = x->parent) splay(x), x->ch[1] = t;
        return t;
    }
    int find(int u){
        node *x = &vertex[u];
        access(x), splay(x);
        node *now = x;
        while (now->ch[0]) now = now->ch[0];
        return ind(now);
    }
    void makeroot(int u) {
        node *x = &vertex[u];
        access(x), splay(x);
        x->inv ^= 1;
    }
	void link(int u, int v) {
        makeroot(u);
        if(find(u) != find(v)) vertex[u].parent = &vertex[v];
    }
	void cut(int u, int v){
		makeroot(u);
        access(&vertex[v]), splay(&vertex[v]);
        if (vertex[u].parent != &vertex[v] || vertex[u].ch[1]) return;
        vertex[u].parent = vertex[v].ch[0] = nullptr;
	}
    void single_modify(int u, int x) {
        vertex[u].val = x;
        splay(&vertex[u]);
    }
    node *interval(int u, int v) {
        makeroot(u);
        access(&vertex[v]), splay(&vertex[v]);
        return &vertex[v];
    }
    node *range_query(int x, int y) {
        return interval(x, y);
    }
};

int32_t main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);

    int n, m, T; cin >> n >> m >> T;
    int cnt = 0;
    lct t(n+m+T);
    vector<pair<int, int>> adj;
    map<pair<int, int>, int> mp;

    auto add = [&](int u, int v, int clock) {
        if (u > v) swap(u, v);
        int mid = n + cnt++;
        adj.push_back({u, v});
        mp[{u, v}] = mid;
        t.vertex[mid].val = clock;
        t.link(u, mid), t.link(mid, v);
    };

    struct op { int u, v, ins, del; };
    vector<op> ops;
    map<pair<int, int>, int> tmp;
    for (int i = 0; i < m; ++i) {
        int u, v; cin >> u >> v; --u, --v;
        if (u > v) swap(u, v);
        ops.push_back({u, v, 0, T+1}), tmp[{u, v}] = i;
    }
    for (int i = 0, idx = m; i < T; ++i) {
        int opt, u, v; cin >> opt >> u >> v; --u, --v;
        if (u > v) swap(u, v);
        if (opt == 1) ops.push_back({u, v, i+1, T+1}), tmp[{u, v}] = idx++;
        else ops[tmp[{u, v}]].del = i+1;
    }
    multiset<int, greater<int>> edges;
    rep(i, 0, n) t.vertex[i].val = T+2;
    for (int clock = 0, i = 0; clock <= T; ++clock) {
        for (; i < sz(ops) && ops[i].ins <= clock; ++i) {
            int u = ops[i].u, v = ops[i].v, del = ops[i].del;
            if (t.find(u) != t.find(v)) add(u, v, del), edges.insert(del);
            else {
                auto *x = t.interval(u, v);
                if (x->minv >= del) continue;
                int mid = x->minp;
                auto [l, r] = adj[mid-n];
                auto it = edges.find(t.vertex[mid].val);
                if (it != edges.end()) edges.erase(it);
                t.cut(l, mid), t.cut(mid, r);
                edges.insert(del);
                add(u, v, del);
            }
        }
        auto it = edges.lower_bound(clock);
        edges.erase(it, edges.end());
        printf("%d ", n - sz(edges));
    }
    printf("\n");

    return 0;
}
No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
Previous
Next