BZOJ3673 可持久化并查集 by zky
2014-07-31 10:15
393 查看
[Solution]
It's said that it's a very classic problem, although I don't know what the correct solution is.
My solution is to use treap to take the place of vector to make it persistent.
It's said that it's a very classic problem, although I don't know what the correct solution is.
My solution is to use treap to take the place of vector to make it persistent.
Very ugly... [code]#include <cstdio> #include <cstdlib> #include <memory.h> #include <algorithm> using namespace std; #ifdef WIN32 #define getRand() ((rand() << 16) | rand()) #else #define getRand() rand() #endif const int maxa = 20009; const int maxn = maxa * 40; int n, m, ls[maxn], rs[maxn], sz[maxn], vl[maxn], w[maxn], rt[maxa], tn; int newNode(int v0) { int p = ++ tn; ls[p] = 0; rs[p] = 0; sz[p] = 1; vl[p] = v0; w[p] = getRand(); return p; } inline void update(const int& x) { sz[x] = sz[ls[x]] + sz[rs[x]] + 1; } int merge(int p, int q) { if (!p) return q; else if (!q) return p; else if (w[p] > w[q]) { rs[p] = merge(rs[p], q); update(p); return p; } else { ls[q] = merge(p, ls[q]); update(q); return q; } } int valOn(int p, int p0) { if (sz[ls[p]] + 1 == p0) return vl[p]; else if (sz[ls[p]] >= p0) return valOn(ls[p], p0); else return valOn(rs[p], p0 - sz[ls[p]] - 1); } int changeNew(int p, int p0, int v0) { int q = ++ tn; vl[q] = vl[p]; ls[q] = ls[p]; rs[q] = rs[p]; sz[q] = sz[p]; if (sz[ls[p]] + 1 == p0) vl[q] = v0; else if (sz[ls[p]] >= p0) ls[q] = changeNew(ls[p], p0, v0); else rs[q] = changeNew(rs[p], p0 - sz[ls[p]] - 1, v0); update(q); return q; } int getRoot(int c, int x) { int r0 = valOn(rt[c], x); if (r0 == x) return r0; else { int rx = getRoot(c, r0); return rx; } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("o1.txt", "w", stdout); #endif srand(12093409); scanf("%d%d", &n, &m); tn = 0; rt[0] = 0; for (int i = 1; i <= n; i ++) rt[0] = merge(rt[0], newNode(i)); for (int i = 0; i < m; i ++) { int opt, x, y; scanf("%d", &opt); if (opt == 1) { scanf("%d%d", &x, &y); x = getRoot(i, x); y = getRoot(i, y); if (rand() & 1) rt[i + 1] = changeNew(rt[i], x, y); else rt[i + 1] = changeNew(rt[i], y, x); } else if (opt == 2) { int k; scanf("%d", &k); rt[i + 1] = rt[k]; } else if (opt == 3) { int x, y; scanf("%d%d", &x, &y); x = getRoot(i, x); y = getRoot(i, y); if (x == y) printf("1\n"); else printf("0\n"); rt[i + 1] = rt[i]; } } }
相关文章推荐
- BZOJ 3674: 可持久化并查集加强版/BZOJ 3673: 可持久化并查集 by zky 可持久化线段树
- bzoj 3673可持久化并查集 by zky
- 【BZOJ3673】【可持久化并查集】可持久化并查集 by zky
- BZOJ 3673 可持久化并查集 by zky 可持久化并查集
- BZOJ 3673: 可持久化并查集 by zky
- bzoj 3673: 可持久化并查集 by zky
- [BZOJ3673]可持久化并查集 by zky-主席树
- bzoj3673 可持久化并查集by zky
- bzoj 3673: 可持久化并查集 by zky
- 【BZOJ 3674】可持久化并查集加强版&【BZOJ 3673】可持久化并查集 by zky 用可持久化线段树破之
- bzoj 3673: 可持久化并查集 by zky
- BZOJ 3673/3674(可持久化并查集 by zky,可持久化并查集加强版-可持久化数组)
- 【BZOJ】3673: 可持久化并查集 by zky
- bzoj3673: 可持久化并查集 by zky
- Bzoj 3673: 可持久化并查集 by zky(主席树+启发式合并)
- 【bzoj3673】可持久化并查集 by zky
- BZOJ 3673 / 3674 可持久化并查集 by zky [主席树]
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
- 【BZOJ3673】&&【BZOJ3674】: 可持久化并查集 by zky 可持久化线段树
- BZOJ 3673: 可持久化并查集 by zky