1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| #include <bits/stdc++.h> using namespace std; using LL = long long; #define FOR(i, x, y) for (decay<decltype(y)>::type i = (x), _##i = (y); i < _##i; ++i) #define FORD(i, x, y) for (decay<decltype(x)>::type i = (x), _##i = (y); i > _##i; --i) #ifdef zerol #define dbg(args...) do { cout << "\033[32;1m" << #args << " -> "; err(args); } while (0) #else #define dbg(...) #endif void err() { cout << "\033[39;0m" << endl; } template<template<typename...> class T, typename t, typename... Args> void err(T<t> a, Args... args) { for (auto x: a) cout << x << ' '; err(args...); } template<typename T, typename... Args> void err(T a, Args... args) { cout << a << ' '; err(args...); } // ----------------------------------------------------------------------------- const int maxm = 5E5 + 5E3 + 100, maxn = 5E3 + 100; const int INF = 1E9;
namespace lct { extern struct P* null; struct P { P *fa, *ls, *rs; int v; P *minp; bool rev;
bool has_fa() { return fa->ls == this || fa->rs == this; } bool d() { return fa->ls == this; } P*& c(bool x) { return x ? ls : rs; } void do_rev() { if (this == null) return; rev ^= 1; swap(ls, rs); }
P* up() { minp = this; if (minp->v > ls->minp->v) minp = ls->minp; if (minp->v > rs->minp->v) minp = rs->minp; return this; } void down() { if (rev) { rev = 0; ls->do_rev(); rs->do_rev(); }} void all_down() { if (has_fa()) fa->all_down(); down(); } } *null = new P{0, 0, 0, INF, 0, 0}, pool[maxm], *pit = pool; void rot(P* o) { bool dd = o->d(); P *f = o->fa, *t = o->c(!dd); if (f->has_fa()) f->fa->c(f->d()) = o; o->fa = f->fa; if (t != null) t->fa = f; f->c(dd) = t; o->c(!dd) = f->up(); f->fa = o; } void splay(P* o) { o->all_down(); while (o->has_fa()) { if (o->fa->has_fa()) rot(o->d() ^ o->fa->d() ? o : o->fa); rot(o); } o->up(); } void access(P* u, P* v = null) { if (u == null) return; splay(u); u->rs = v; access(u->up()->fa, u); } void make_root(P* o) { access(o); splay(o); o->do_rev(); } void split(P* u, P* v) { make_root(u); access(v); splay(v); } bool linked(P* u, P* v) { split(u, v); return u == v || u->fa != null; } void link(P* u, P* v) { make_root(u); u->fa = v; } void cut(P* u, P* v) { split(u, v); u->fa = v->ls = null; v->up(); } }
using namespace lct; int n, m; P *p[maxn]; struct Q { int tp, u, v, l, r; }; vector<Q> q;
int main() { null->minp = null; cin >> n >> m; FOR (i, 1, n + 1) p[i] = new (pit++) P{null, null, null, INF, p[i], 0}; int clk = 0; map<pair<int, int>, int> mp; FOR (_, 0, m) { int tp, u, v; scanf("%d%d%d", &tp, &u, &v); if (u > v) swap(u, v); if (tp == 0) mp.insert({{u, v}, clk}); else if (tp == 1) { auto it = mp.find({u, v}); assert(it != mp.end()); q.push_back({1, u, v, it->second, clk}); mp.erase(it); } else q.push_back({0, u, v, clk, clk}); ++clk; } for (auto& x: mp) q.push_back({1, x.first.first, x.first.second, x.second, clk}); sort(q.begin(), q.end(), [](const Q& a, const Q& b)->bool { return a.l < b.l; }); map<P*, int> mp2; FOR (i, 0, q.size()) { Q& cur = q[i]; int u = cur.u, v = cur.v; if (cur.tp == 0) { if (!linked(p[u], p[v])) puts("N"); else puts(p[v]->minp->v >= cur.r ? "Y" : "N"); continue; } if (linked(p[u], p[v])) { P* t = p[v]->minp; if (t->v > cur.r) continue; Q& old = q[mp2[t]]; cut(p[old.u], t); cut(p[old.v], t); } P* t = new (pit++) P {null, null, null, cur.r, t, 0}; mp2[t] = i; link(t, p[u]); link(t, p[v]); } }
|