zoukankan      html  css  js  c++  java
  • 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
    ", find(root[i],a)->u==find(root[i],b)->u );
    85         }
    86     }
    87 }
    View Code
  • 相关阅读:
    兔子数
    忠诚
    mysql字段名与关键字冲突(near "to":syntax error)
    C/C++使用心得:enum与int的相互转换
    ubuntu重新安装 apache2
    ubuntu 删除mysql
    Notepad++ 代码格式化
    linux文件字符集转换(utf8-gb2312)
    字符编码详解——彻底理解掌握编码知识,“乱码”不复存在
    c语言判断是否是utf8字符串,计算字符个数
  • 原文地址:https://www.cnblogs.com/idy002/p/4558525.html
Copyright © 2011-2022 走看看