zoukankan      html  css  js  c++  java
  • bzoj 3673&3674: 可持久化并查集 by zky

    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 6
    1 1 2
    3 1 2
    2 0
    3 1 2
    2 1
    3 1 2

    Sample Output

    1
    0
    1

    题解:

    首先普通并查集操作中,是靠fa这个数组维护的

    所以要可持久并查集,就要可持久化fa数组,所以用到可持久化线段树维护.

    注意要路径压缩

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #define RG register
     8 #define il inline
     9 using namespace std;
    10 const int N=2000005,M=20005;
    11 int gi(){
    12     int str=0;char ch=getchar();
    13     while(ch>'9' || ch<'0')ch=getchar();
    14     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
    15     return str;
    16 }
    17 int n,m,tot=0,root[M];
    18 struct node{
    19     int ls,rs,fa;
    20 }t[N];
    21 il void build(int &rt,int l,int r){
    22     rt=++tot;
    23     if(l==r){
    24         t[rt].fa=l;
    25         return ;
    26     }
    27     int mid=(l+r)>>1;
    28     build(t[rt].ls,l,mid);build(t[rt].rs,mid+1,r);
    29 }
    30 il int query(int rt,int l,int r,int sa){
    31     if(l==r)
    32         return rt;
    33     int mid=(l+r)>>1;
    34     if(sa>mid)return query(t[rt].rs,mid+1,r,sa);
    35     else return query(t[rt].ls,l,mid,sa);
    36 }
    37 il void updata(int &rt,int last,int l,int r,int sa,int to){
    38     rt=++tot;t[rt]=t[last];
    39     if(l==r){
    40         t[rt].fa=to;
    41         return ;
    42     }
    43     int mid=(l+r)>>1;
    44   if(sa>mid)updata(t[rt].rs,t[last].rs,mid+1,r,sa,to);
    45     else updata(t[rt].ls,t[last].ls,l,mid,sa,to);
    46 }
    47 il int find(int x,int i){
    48     int c=query(root[i],1,n,x);
    49     if(t[c].fa==x)return x;
    50     int d=find(t[c].fa,i);
    51     updata(root[i],root[i],1,n,x,d);
    52     return d;
    53 }
    54 void work()
    55 {
    56     int flag,x,y,fx,fy;
    57     n=gi();m=gi();
    58     build(root[0],1,n);
    59     for(int i=1;i<=m;i++){
    60         flag=gi();x=gi();
    61         if(flag==1){
    62             y=gi();
    63             root[i]=root[i-1];
    64             fx=find(x,i);fy=find(y,i);
    65             if(fx==fy)continue;
    66             updata(root[i],root[i-1],1,n,fx,fy);
    67         }
    68         else if(flag==2)root[i]=root[x];
    69         else{
    70             y=gi();
    71             root[i]=root[i-1];
    72             fx=find(x,i);fy=find(y,i);
    73             if(fx==fy)puts("1");
    74             else puts("0");
    75         }
    76     }
    77 }
    78 
    79 int main()
    80 {
    81     work();
    82     return 0;
    83 }
  • 相关阅读:
    jQuery中的观察者模式(Observer Pattern)
    jQuery异步获取json数据的2种方式
    jQuery制作水平多级下拉菜单
    简单说明CGI和动态请求是什么
    五种IO模型透彻分析
    不可不知的socket和TCP连接过程
    零复制(zero copy)技术
    编译httpd细节
    ansible编译httpd playbook示例
    翻译:CREATE DATABASE语句
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7399498.html
Copyright © 2011-2022 走看看