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
| #include <bits/stdc++.h> #define fi first #define se second #define eb emplace_back #define pb push_back const int N = 4e5 + 100; int n, m; std::vector<std::pair<int, int>> ans, live; struct LCT //不换根LCT { struct Node { Node *ch[2], *fa; int si; bool be; } tr[N]; const Node _null = (Node){nullptr, nullptr, nullptr, 0, false}; Node *null = (Node*)&_null, *tot = tr; static Node ttry; LCT(){ ttry = Node{}; } Node* _new(bool be) { *tot = (Node){null, null, null, be, be}; return tot++; } void up(Node *x){ x->si = x->ch[0]->si + x->ch[1]->si + x->be; } bool is_rt(Node *x){ return x->fa->ch[0] != x && x->fa->ch[1] != x; } void rot(Node *x) { Node *y = x->fa, *z = y->fa; int k = y->ch[1] == x; if (!is_rt(y)) z->ch[z->ch[1] == y] = x; x->fa = z; y->ch[k] = x->ch[k ^ 1], x->ch[k ^ 1]->fa = y; x->ch[k ^ 1] = y, y->fa = x; up(y), up(x); } void splay(Node *x) { Node *y, *z; while (!is_rt(x)) { y = x->fa, z = y->fa; if (!is_rt(y)) (y->ch[1] == x) ^ (z->ch[1] == y) ? rot(x) : rot(y); rot(x); } } Node* access(Node *x) { Node *t = null; for (; x != null; t = x, x = x->fa) splay(x), x->ch[1] = t, up(x); return t; } void cut(Node *x) { access(x), splay(x); x->ch[0]->fa = null, x->ch[0] = null; up(x); } void lk(Node *x, Node *y){ splay(x), x->fa = y; } int ask(Node *x, Node *y) { int res = 0; access(x), splay(x); res += x->si; Node *t = access(y); splay(y); res += y->si; access(t), splay(t); res -= t->si << 1; return res; } } lct; LCT::Node *now; std::vector<LCT::Node*> fuc; struct Opt{ int op, pos; LCT::Node *x, *y; }; std::vector<Opt> q; void make(int l, int r){ live.eb(l, r), fuc.eb(lct._new(1)); } int main() { scanf("%d %d", &n, &m); make(1, n); lct.lk(now = lct._new(0), fuc.back()); while (m--) { int op, l, r, x; scanf("%d %d %d", &op, &l , &r); if (op == 0) make(l, r), lct.lk(fuc.back(), now); else if (op == 1) { scanf("%d", &x); l = std::max(l, live[x - 1].fi); r = std::min(r, live[x - 1].se); if (l > r) continue; auto t = lct._new(0); lct.lk(t, now); q.pb({1, l, t, fuc[x - 1]}); q.pb({1, r + 1, t, now}); now = t; } else scanf("%d", &x), q.pb({-m, l, fuc[r - 1], fuc[x - 1]}); } std::sort(q.begin(), q.end(), [&](Opt x, Opt y){ return x.pos == y.pos ? x.op > y.op : x.pos < y.pos; }); for (int i = 1, j = 0; i <= n; ++i) for (; j < q.size() && q[j].pos <= i; ++j) if (q[j].op > 0) lct.cut(q[j].x), lct.lk(q[j].x, q[j].y); else ans.eb(q[j].op, lct.ask(q[j].x, q[j].y)); std::sort(ans.begin(), ans.end()); for (auto t : ans) printf("%d\n", t.se); return 0; }
|