咕咕咕


容易想到用线段树分治。然而我不断 WA。这说明要写强力的 gen。

有个问题就是一个边不能加入的时候,要改掉它的颜色,在后来仍然加入。

#include <bits/stdc++.h>

const int MAXN = 500010;
int st[MAXN], ids[MAXN], top;
struct dsu {
    int idx;
    int fa[MAXN], sz[MAXN]; bool fae[MAXN];
    void init(int ix, int n) {
        idx = ix;
        for (int i = 1; i <= n; ++i) fa[i] = i, sz[i] = 1;
    }
    std::pair<int, int> find(int x) {
        int res = 0;
        while (x != fa[x]) res ^= fae[x], x = fa[x];
        return std::make_pair(x, res);
    }
    void pop() {
        int x = st[top], y = fa[x];
        sz[y] -= sz[x]; fa[x] = x; fae[x] = 0;
        --top;
    }
    bool link(int x, int y) {
        int ex, ey;
        std::tie(x, ex) = find(x);
        std::tie(y, ey) = find(y);
        if (x != y) {
            if (sz[x] > sz[y]) std::swap(x, y);
            st[++top] = x, ids[top] = idx;
            fae[x] = ex ^ ey ^ 1;
            sz[y] += sz[x];
            fa[x] = y;
            return true;
        }
        return (ex ^ ey) == 1;
    }
} ss[51];
int n, m, K, Q;
int xs[MAXN], ys[MAXN];
int col[MAXN], lst[MAXN], disa[MAXN];
const int MAXQ = MAXN * 50;
struct qry { int id, c; } fir[MAXN];
int qh[MAXN << 2], qn[MAXQ], qt[MAXQ], tot;
int pre[MAXN], faqry[MAXN], elst[MAXN];
int find(int x) { return x == faqry[x] ? x : faqry[x] = find(faqry[x]); }
void addq(int u, int l, int r, int L, int R, int v) {
    if (L <= l && r <= R) {
        qn[++tot] = qh[u]; qt[qh[u] = tot] = v;
        return ;
    }
    int mid = l + r >> 1;
    if (L <= mid) addq(u << 1, l, mid, L, R, v);
    if (mid < R) addq(u << 1 | 1, mid + 1, r, L, R, v);
}
void addq(int l, int r, int id) {
    fir[l] = (qry) {id, col[id]}; faqry[l] = l;
    pre[l] = elst[id]; elst[id] = l;
    if (l + 1 <= r) addq(1, 1, Q, l + 1, r, l);
}
void solve(int u, int l, int r) {
    int nowtop = top;
    for (int i = qh[u]; i; i = qn[i]) {
        const int v = find(qt[i]);
        if (v) {
            const qry t = fir[v];
            ss[t.c].link(xs[t.id], ys[t.id]);
        }
    }
    if (l == r) {
        static qry t; t = fir[l];
        disa[l] = !ss[t.c].link(xs[t.id], ys[t.id]);
        if (disa[l]) faqry[l] = pre[faqry[l]];
    } else {
        int mid = l + r >> 1;
        solve(u << 1, l, mid); solve(u << 1 | 1, mid + 1, r);
    }
    while (top > nowtop) ss[ids[top]].pop();
}
int main() {
    std::ios_base::sync_with_stdio(false), std::cin.tie(0);
    std::cin >> n >> m >> K >> Q;
    for (int i = 1; i <= K; ++i) ss[i].init(i, n);
    for (int i = 1; i <= m; ++i)
        std::cin >> xs[i] >> ys[i];
    for (int i = 1, e, v; i <= Q; ++i) {
        std::cin >> e >> v;
        if (col[e]) addq(lst[e], i - 1, e);
        col[e] = v, lst[e] = i;
    }
    for (int i = 1; i <= m; ++i) if (col[i])
        addq(lst[i], Q, i);
    solve(1, 1, Q);
    const char out[][10] = {"YES", "NO"};
    for (int i = 1; i <= Q; ++i)
        std::cout << out[disa[i]] << '\n';
    return 0;
}
12-23 06:58