diff --git a/LibreOJ/186/186.cpp b/LibreOJ/186/186.cpp new file mode 100644 index 00000000..2f1e6958 --- /dev/null +++ b/LibreOJ/186/186.cpp @@ -0,0 +1,230 @@ +#include +#include +#include +#include + +using std::cin; +using std::cout; +const char endl = '\n'; + +const int N = 3e5 + 5; + +// Link-Cut Tree +class LinkCutTree { + private: + std::stack st; + + struct node { + int p, // 父亲节点 + l, // 左儿子 + r; // 右儿子 + int pre; + int val, // 节点值 + sum; // 异或和 + int key; // 权值 + bool rev; // 翻转标记 + + node() + : p(0), l(0), r(0), pre(0), val(0), sum(0), key(rand()), rev(false) {} + } tr[N]; + + void pushup(int u) { + // 计算异或和 + tr[u].sum = tr[tr[u].l].sum ^ tr[u].val ^ tr[tr[u].r].sum; + + // 标记父亲节点 + if (tr[u].l) + tr[tr[u].l].p = u; + if (tr[u].r) + tr[tr[u].r].p = u; + } + + void pushdown(int u) { + if (!tr[u].rev) + return; + + tr[u].rev = false; + std::swap(tr[u].l, tr[u].r); + tr[tr[u].l].rev ^= 1; + tr[tr[u].r].rev ^= 1; + } + + std::pair split(int u) { + if (st.empty()) { + pushdown(u); + auto t = std::make_pair(u, tr[u].r); + tr[u].r = 0; + pushup(u); + + return t; + } + + bool d = st.top() ^ tr[u].rev; + st.pop(); + + pushdown(u); + + if (d) { + auto t = split(tr[u].l); + tr[u].l = t.second; + pushup(u); + + return std::make_pair(t.first, u); + } + + auto t = split(tr[u].r); + tr[u].r = t.first; + pushup(u); + + return std::make_pair(u, t.second); + } + + // 合并 + int merge(int x, int y) { + if (!x || !y) + return x | y; + + if (tr[x].key < tr[y].key) { + pushdown(x); + tr[x].r = merge(tr[x].r, y); + pushup(x); + return x; + } + + pushdown(y); + tr[y].l = merge(x, tr[y].l); + pushup(y); + return y; + } + + // 是否是根节点 + bool isRoot(int u) { + return !tr[u].p || (tr[tr[u].p].l != u && tr[tr[u].p].r != u); + } + + // 查找根节点 + int findRoot(int u) { + while (!st.empty()) + st.pop(); + while (!isRoot(u)) { + st.push(tr[tr[u].p].l == u); + u = tr[u].p; + } + return u; + } + + int findLeft(int u) { + u = findRoot(u); + pushdown(u); + while (tr[u].l) { + u = tr[u].l; + pushdown(u); + } + return u; + } + + int access(int u) { + int lst = 0; + + while (u) { + auto t = split(findRoot(u)); + tr[findLeft(lst)].pre = 0; + lst = merge(t.first, lst); + tr[findLeft(t.second)].pre = u; + u = tr[findLeft(lst)].pre; + } + + return lst; + } + + void makeRoot(int u) { + tr[access(u)].rev ^= 1; + } + + public: + int getRoot(int u) { + return findLeft(access(u)); + } + + void link(int x, int y) { + makeRoot(x); + tr[x].pre = y; + } + + void cut(int x, int y) { + makeRoot(x); + access(y); + access(x); + tr[y].pre = 0; + } + + int query(int x, int y) { + makeRoot(x); + access(y); + + auto t = split(findRoot(y)); + int res = tr[t.first].sum; + merge(t.first, t.second); + + return res; + } + + void change(int u, int val) { + makeRoot(u); + auto t = split(findRoot(u)); + tr[u].val = val; + merge(t.first, t.second); + } + + void set(int u, int val) { + tr[u].sum = tr[u].val = val; + } +} lct; + +int n, m; + +int main() { + std::ios::sync_with_stdio(false); + cin.tie(nullptr); + + cin >> n >> m; + + for (int i = 1, x; i <= n; i++) { + cin >> x; + + lct.set(i, x); + } + + while (m--) { + int op, x, y; + + cin >> op >> x >> y; + + switch (op) { + case 0: { + cout << lct.query(x, y) << endl; + + break; + } + case 1: { + if (lct.getRoot(x) != lct.getRoot(y)) { + lct.link(x, y); + } + + break; + } + case 2: { + lct.cut(x, y); + + break; + } + case 3: { + lct.change(x, y); + + break; + } + } + } + + return 0; +} diff --git a/LibreOJ/186/data/tree1.ans b/LibreOJ/186/data/tree1.ans new file mode 100644 index 00000000..e0fca11a --- /dev/null +++ b/LibreOJ/186/data/tree1.ans @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:487bbad82294aa14f2d1a6ff7355771208dc9e2dc8149e20a068cfe7dfb87340 +size 269885 diff --git a/LibreOJ/186/data/tree1.in b/LibreOJ/186/data/tree1.in new file mode 100644 index 00000000..1cc0f65e --- /dev/null +++ b/LibreOJ/186/data/tree1.in @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:942eeed478c5a181f63cd15a685d3bbed419f35343b6234386fa1669ddc24b8c +size 1693097 diff --git a/LibreOJ/186/data/tree10.ans b/LibreOJ/186/data/tree10.ans new file mode 100644 index 00000000..ef9b8acf --- /dev/null +++ b/LibreOJ/186/data/tree10.ans @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53ce624b8d42e7a244a5a769a73ae480b667e8ea97a708157ffce4e3e8190016 +size 384849 diff --git a/LibreOJ/186/data/tree10.in b/LibreOJ/186/data/tree10.in new file mode 100644 index 00000000..3b082e92 --- /dev/null +++ b/LibreOJ/186/data/tree10.in @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66c10394d6b00965ea07f8857e5a324caa2f4c64d86b21dffa9b68d70f42eb9f +size 2426607 diff --git a/LibreOJ/186/data/tree2.ans b/LibreOJ/186/data/tree2.ans new file mode 100644 index 00000000..fb04baed --- /dev/null +++ b/LibreOJ/186/data/tree2.ans @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0d9b8c199a49751ee557e626eaf29b425442235b316ac005e8b1cf2095e1e97 +size 2467 diff --git a/LibreOJ/186/data/tree2.in b/LibreOJ/186/data/tree2.in new file mode 100644 index 00000000..0f2cfce1 --- /dev/null +++ b/LibreOJ/186/data/tree2.in @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eee28e01b27b6f436f4a14426644111c7874330196a7ed41bc085fcffa87f83b +size 21146 diff --git a/LibreOJ/186/data/tree3.ans b/LibreOJ/186/data/tree3.ans new file mode 100644 index 00000000..110d4046 --- /dev/null +++ b/LibreOJ/186/data/tree3.ans @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7db423cbf162004fdfa201b28a15d2668151a125d48320dd590592c6b6a1a62f +size 2135393 diff --git a/LibreOJ/186/data/tree3.in b/LibreOJ/186/data/tree3.in new file mode 100644 index 00000000..adf04a5c --- /dev/null +++ b/LibreOJ/186/data/tree3.in @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebc429cbc055eb463eea78b8e65c2adebf85773c4f086ce6e59d8cecf0607499 +size 4466295 diff --git a/LibreOJ/186/data/tree4.ans b/LibreOJ/186/data/tree4.ans new file mode 100644 index 00000000..3df86438 --- /dev/null +++ b/LibreOJ/186/data/tree4.ans @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1b39118d817ef1a1153697f111de4f06e63d9c58a6b11f9cde7bb3e8c60a6c4 +size 1494779 diff --git a/LibreOJ/186/data/tree4.in b/LibreOJ/186/data/tree4.in new file mode 100644 index 00000000..e6f58728 --- /dev/null +++ b/LibreOJ/186/data/tree4.in @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e796aa7ae4cef11a758e2fb91db4c93fb6c22b64349c5cefd0357c070199154 +size 2571795 diff --git a/LibreOJ/186/data/tree5.ans b/LibreOJ/186/data/tree5.ans new file mode 100644 index 00000000..6d7c3e4c --- /dev/null +++ b/LibreOJ/186/data/tree5.ans @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4fe6573dd935cc13060d11ad21f44dcb9667debe30d10a0f2dd52a97e00d3dfc +size 38869 diff --git a/LibreOJ/186/data/tree5.in b/LibreOJ/186/data/tree5.in new file mode 100644 index 00000000..480d6970 --- /dev/null +++ b/LibreOJ/186/data/tree5.in @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f3a2e512ba6ff1da54e09124e0c77849e51fe396303d20e2c3bfba0b52b084c +size 224122 diff --git a/LibreOJ/186/data/tree6.ans b/LibreOJ/186/data/tree6.ans new file mode 100644 index 00000000..dee295ba --- /dev/null +++ b/LibreOJ/186/data/tree6.ans @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:925b6fb3d451806574741899bb649364ef3adf4e71b0cd7316179fe5c1e9398f +size 153604 diff --git a/LibreOJ/186/data/tree6.in b/LibreOJ/186/data/tree6.in new file mode 100644 index 00000000..d4c408d7 --- /dev/null +++ b/LibreOJ/186/data/tree6.in @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:005a6a288e7de5e8d71f4ff0e61992475a2e88b01958b67e4c225b3a7b529be6 +size 958470 diff --git a/LibreOJ/186/data/tree7.ans b/LibreOJ/186/data/tree7.ans new file mode 100644 index 00000000..f1df9ef0 --- /dev/null +++ b/LibreOJ/186/data/tree7.ans @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:154b6b2c5c006716f04f918f2aa8d88386c107310f8c0daab27c56e1457fd87f +size 1154858 diff --git a/LibreOJ/186/data/tree7.in b/LibreOJ/186/data/tree7.in new file mode 100644 index 00000000..1548f088 --- /dev/null +++ b/LibreOJ/186/data/tree7.in @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19d050989f0ca9c97d3135321b3ccf82b1a701f8644ac19a97b347da2713ec3e +size 7690444 diff --git a/LibreOJ/186/data/tree8.ans b/LibreOJ/186/data/tree8.ans new file mode 100644 index 00000000..ede63406 --- /dev/null +++ b/LibreOJ/186/data/tree8.ans @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0850fd74de82a693dc1f9ed470b092acc5c5304a394e131a321bfbe45bf03d0b +size 77290 diff --git a/LibreOJ/186/data/tree8.in b/LibreOJ/186/data/tree8.in new file mode 100644 index 00000000..c5ce06ac --- /dev/null +++ b/LibreOJ/186/data/tree8.in @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:543f78df01ef034bfea33e1ca53f68ce92d1f0e638835795c791bda6fd74e135 +size 468289 diff --git a/LibreOJ/186/data/tree9.ans b/LibreOJ/186/data/tree9.ans new file mode 100644 index 00000000..bbe3f97b --- /dev/null +++ b/LibreOJ/186/data/tree9.ans @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a14fa1568da1b584766284081861c3022d051c26af8733f3e45a875ee18430c6 +size 4023 diff --git a/LibreOJ/186/data/tree9.in b/LibreOJ/186/data/tree9.in new file mode 100644 index 00000000..b159285c --- /dev/null +++ b/LibreOJ/186/data/tree9.in @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ac4d88896dddba22879b1232945ed954394a5e140b4144dcb873f10347b181d +size 20575