bzoj 3673 可持久化并查集

 

本质上是维护两个可持久化数组,用可持久化线段树维护.

 

 1 /**************************************************************
 2     Problem: 3673
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:76 ms
 7     Memory:13780 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <algorithm>
12 #define N 20010
13 using namespace std;
14  
15 struct Node {
16     int u, p, s;
17     Node *ls, *rs;
18 }pool[N*33], *tail=pool, *root[N];
19  
20 int n, m;
21 Node *build( int lf, int rg ) {
22     Node *nd = ++tail;
23     if( lf==rg ) {
24         nd->u = lf;
25         nd->p = lf;
26         nd->s = 1;
27         return nd;
28     }
29     int mid=(lf+rg)>>1;
30     nd->ls = build( lf, mid );
31     nd->rs = build( mid+1, rg );
32     return nd;
33 }
34 Node *modify( Node *nd, int lf, int rg, int u, int p, int s ) {
35     Node *nn = ++tail;
36     if( lf==rg ) {
37         nn->u = u;
38         nn->p = p;
39         nn->s = s;
40         return nn;
41     }
42     int mid=(lf+rg)>>1;
43     if( u<=mid ) {
44         nn->ls = modify( nd->ls, lf, mid, u, p, s );
45         nn->rs = nd->rs;
46     } else {
47         nn->ls = nd->ls;
48         nn->rs = modify( nd->rs, mid+1, rg, u, p, s );
49     }
50     return nn;
51 }
52 Node *query( Node *nd, int lf, int rg, int u ) {
53     if( lf==rg ) return nd;
54     int mid=(lf+rg)>>1;
55     if( u<=mid ) return query(nd->ls,lf,mid,u);
56     else return query(nd->rs,mid+1,rg,u);
57 }
58  
59 Node *find( Node *r, int a ) {
60     Node *na = query(r,1,n,a);
61     while( na->u!=na->p ) na=query(r,1,n,na->p);
62     return na;
63 }
64 int main() {
65     scanf( "%d%d", &n, &m );
66     root[0] = build(1,n);
67     for( int i=1,opt,a,b,k; i<=m; i++ ) {
68         scanf( "%d", &opt );
69         if( opt==1 ) {
70             scanf( "%d%d", &a, &b );
71             root[i] = root[i-1];
72             Node *na = find(root[i],a);
73             Node *nb = find(root[i],b);
74             if( na==nb ) continue;
75             if( na->s > nb->s ) swap(na,nb);
76             root[i] = modify( root[i], 1, n, na->u, nb->u, na->s );
77             root[i] = modify( root[i], 1, n, nb->u, nb->u, na->s+nb->s );
78         } else if( opt==2 ) {
79             scanf( "%d", &k );
80             root[i] = root[k];
81         } else {
82             scanf( "%d%d", &a, &b );
83             root[i] = root[i-1];
84             printf( "%d\n", find(root[i],a)->u==find(root[i],b)->u );
85         }
86     }
87 }
View Code

 

posted @ 2015-06-07 15:37  idy002  阅读(127)  评论(0编辑  收藏  举报