AC代码,求赞
2025-11-15 17:57:15
发布于:上海
13阅读
0回复
0点赞
#include <bits/stdc++.h>
using namespace std;
struct PairHash {
template <class T1, class T2>
size_t operator () (const pair<T1, T2>& p) const {
return hash<T1>{}(p.first) ^ (hash<T2>{}(p.second) << 1);
}
};
struct DSU {
vector<int> fa, sz;
struct Node { int x, y; };
vector<Node> st;
int n;
void init(int n_) {
n = n_;
fa.resize(n + 1);
iota(fa.begin(), fa.end(), 0);
sz.assign(n + 1, 1);
st.clear();
}
int find(int x) const {
while (fa[x] != x) x = fa[x];
return x;
}
int snapshot() const { return st.size(); }
bool merge(int u, int v) {
u = find(u);
v = find(v);
if (u == v) return false;
if (sz[u] > sz[v]) swap(u, v);
st.push_back({u, v});
fa[u] = v;
sz[v] += sz[u];
return true;
}
void rollback(int snap) {
while (st.size() > snap) {
auto m = st.back();
st.pop_back();
sz[m.y] -= sz[m.x];
fa[m.x] = m.x;
}
}
};
DSU d;
int ans = 0;
struct STG {
int q_cnt;
vector<vector<pair<int, int>>> edge;
vector<pair<int, int>> asks;
void init(int _q_cnt) {
q_cnt = _q_cnt;
edge.resize(4 * _q_cnt);
asks.resize(_q_cnt + 1);
}
void add_edge(int node, int l, int r, int L, int R, int x, int y) {
if (l > R || r < L) return;
if (L <= l && r <= R) {
edge[node].emplace_back(x, y);
return;
}
int mid = (l + r) / 2;
add_edge(2 * node, l, mid, L, R, x, y);
add_edge(2 * node + 1, mid + 1, r, L, R, x, y);
}
void add_ask(int t, int u, int v) {
asks[t] = {u, v};
}
void dfs(int node, int l, int r) {
int snap = d.snapshot();
for (auto &e : edge[node]) d.merge(e.first, e.second);
if (l == r) {
auto [u, v] = asks[l];
if (u && v && d.find(u) == d.find(v)) ans ^= l;
} else {
int mid = (l + r) / 2;
dfs(2 * node, l, mid);
dfs(2 * node + 1, mid + 1, r);
}
d.rollback(snap);
}
};
STG stg;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
d.init(n);
stg.init(q);
unordered_map<pair<int, int>, int, PairHash> cnt, first_add;
for (int t = 1; t <= q; ++t) {
int op, x, y;
cin >> op >> x >> y;
if (x > y) swap(x, y);
auto key = make_pair(x, y);
if (op == 1) {
cnt[key]++;
if (cnt[key] == 1) first_add[key] = t;
} else if (op == 2) {
cnt[key]--;
if (cnt[key] == 0) {
stg.add_edge(1, 1, q, first_add[key], t - 1, x, y);
first_add.erase(key);
}
} else stg.add_ask(t, x, y);
}
for (auto &p : cnt) {
if (p.second) {
auto [x, y] = p.first;
stg.add_edge(1, 1, q, first_add[p.first], q, x, y);
}
}
stg.dfs(1, 1, q);
cout << ans << '\n';
return 0;
}
全部评论 1
赞了
5天前 来自 浙江
0










有帮助,赞一个