【BZOJ3673】【可持久化并查集】可持久化并查集 by zky
2015-03-13 15:56
357 查看
Description
n个集合 m个操作操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
0<n,m<=2*10^4
Input
Output
Sample Input
5 61 1 2
3 1 2
2 0
3 1 2
2 1
3 1 2
Sample Output
10
1
HINT
Source
出题人大S【分析】
出题人给我滚出来!保证不打死你!
真是***了,你题意描述清楚点会死啊。。调了将近2个小时...结果是题目理解错了....尼玛返回也算作操作啊。
思路还是蛮简单的。
用主席树维护一下并查集的fa数组就行了。
按照这种说法树状数组也应该可以可持久化了
/* 唐代李商隐 《无题·昨夜星辰昨夜风》 昨夜星辰昨夜风,画楼西畔桂堂东。 身无彩凤双飞翼,心有灵犀一点通。 隔座送钩春酒暖,分曹射覆蜡灯红。 嗟余听鼓应官去,走马兰台类转蓬。 */ #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #include <utility> #include <iomanip> #include <string> #include <cmath> #include <queue> #include <assert.h> #include <map> #include <ctime> #include <cstdlib> #include <stack> #define LOCAL const int MAXN = 20000 * 10 * 20 + 10; //const int MAXM = 20000 + 10; const int INF = 100000000; const int SIZE = 450; const int maxnode = 0x7fffffff + 10; using namespace std; int n, m;//n为元素总个数 struct SEGTREE{ //路径压缩+启发式合并还要用主席树OAO struct Node{ Node *ch[2]; int l, r; int num;//其实除了叶子节点其他都是打酱油的,num是该节点的fa值 }mem[MAXN], *root[200000 * 10 + 10]; int tot; void init(){ tot = 0; root[0] = NULL; for (int i = 1; i <= 200000 * 10; i++) root[i] = NULL; build(root[0], 1, n); //printf("%d %d\n", root[0]->ch[0]->l, root[0]->ch[0]->r); } Node *NEW(int l, int r){ Node *p = &mem[tot++]; p->l = l; p->r = r; p->num = -1; p->ch[0] = p->ch[1] = NULL; return p; } void build(Node *&t, int l, int r){ if (t == NULL){ t = NEW(l, r); //不要返回 } if (l == r) return; int mid = (l + r) >> 1; build(t->ch[0], l, mid); build(t->ch[1], mid + 1, r); } //t为现在的数将x的num改为val void insert(Node *&t, Node *&last, int x, int val){ if (t == NULL){ t = NEW(last->l, last->r); } if (t->l == x && t->r == x) {t->num = val; return;} int mid = (t->l + t->r) >>1; if (x <= mid){ insert(t->ch[0], last->ch[0], x, val); t->ch[1] = last->ch[1]; } if (x > mid){ insert(t->ch[1], last->ch[1], x, val); t->ch[0] = last->ch[0]; } } //直接修改,不是可持久化的,节省空间 /*void change(Node *&t, int x, int val){ if (t->l == x && t->r == x) {t->num = val;return;} int mid = (t->l + t->r) >> 1; if (x <= mid) change(t->ch[0], x, val); if (x > mid) change(t->ch[1], x, val); }*/ int get(int k, int x){//查找k时刻x的fa值 Node *t = root[k]; while (1){ if (t->l == x && t->r == x) break; int mid = (t->l + t->r) >> 1; if (x <= mid) t = t->ch[0]; else t = t->ch[1]; } return t->num; } }A; int data[MAXN];//真正的操作次数 int cnt = 0;//cnt记录现在的状态 int BIGCNT; int find(int x){ int tmp = A.get(cnt, x); if (tmp < 0) return x; else{ int tmp2 = find(tmp); //A.insert(A.root[cnt + 1], A.root[cnt], x, tmp2); //cnt++; return tmp2; } } //启发式合并 void merge(int x, int y){ //分别代表真实数量 int x_num = -A.get(cnt, x); int y_num = -A.get(cnt ,y); if (x_num > y_num){//将y合并到x上 //这里可以可持久化了 //A.root[cnt + 1] = NULL; A.insert(A.root[BIGCNT + 1], A.root[cnt], x, -(x_num + y_num)); BIGCNT++; //A.root[cnt + 1] = NULL; A.insert(A.root[BIGCNT + 1], A.root[cnt], y, x); BIGCNT++; }else{ //A.root[cnt + 1] = NULL; A.insert(A.root[BIGCNT + 1], A.root[cnt], y, -(x_num + y_num)); BIGCNT++; //A.root[cnt + 1] = NULL; A.insert(A.root[BIGCNT + 1], A.root[cnt], x, y); BIGCNT++; //printf("%d %d %d\n", x, y, find(x)); } } void work(){ int z = 1;//记录操作的 data[0] = 0; cnt = 0; BIGCNT = 0; scanf("%d%d", &n, &m); A.init(); for (int i = 1; i <= m; i++){ int t; scanf("%d", &t); if (t == 2){ int c; scanf("%d", &c);//回到c时刻即操作之后 if (c == 2) printf(""); cnt = data[c]; }else if (t == 1){ int a, b; scanf("%d%d", &a, &b); int xa = find(a), xb = find(b); if (xa == xb) {data[i] = cnt;continue;} merge(xa, xb); cnt = BIGCNT; }else{ int a, b; scanf("%d%d", &a, &b); if (find(a) == find(b)) printf("1\n"); else printf("0\n"); } data[i] = cnt; } //printf("%d", data[6]); } int main(){ work(); return 0; }
View Code
相关文章推荐
- bzoj 3673: 可持久化并查集 by zky
- BZOJ 3673 可持久化并查集 by zky 可持久化并查集
- bzoj 3673: 可持久化并查集 by zky
- BZOJ 3673: 可持久化并查集 by zky
- bzoj 3673: 可持久化并查集 by zky
- bzoj3673 可持久化并查集by zky
- 【BZOJ】3673: 可持久化并查集 by zky
- bzoj3673: 可持久化并查集 by zky
- Bzoj 3673: 可持久化并查集 by zky(主席树+启发式合并)
- 【bzoj3673】可持久化并查集 by zky
- 【BZOJ 3674】可持久化并查集加强版&【BZOJ 3673】可持久化并查集 by zky 用可持久化线段树破之
- BZOJ 3673 / 3674 可持久化并查集 by zky [主席树]
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
- BZOJ 3673/3674(可持久化并查集 by zky,可持久化并查集加强版-可持久化数组)
- BZOJ 3673: 可持久化并查集 by zky
- 【可持久化并查集】BZOJ3673-可持久化并查集 by zky
- [BZOJ3674]可持久化并查集加强版&[BZOJ3673]可持久化并查集 by zky
- 【BZOJ3673】&&【BZOJ3674】: 可持久化并查集 by zky 可持久化线段树
- BZOJ3673 可持久化并查集 by zky
- BZOJ 3673 可持久化并查集 by zky