zoukankan      html  css  js  c++  java
  • bzoj 3674 可持久化并查集加强版

    题目大意:

    n个集合 m个操作 操作有三种(强制在线):

    1 a b 合并a,b所在集合

    2 k 回到第k次操作之后的状态(查询算作操作)

    3 a b 询问a,b是否属于同一集合,是则输出1否则输出0

    思路:

    因为每次只会改一个点的$fa$,可以使用主席树暴力维护,$find$的时候不路径压缩 暴力跳

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MAXN 200100
    15 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    16 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    17 #define ren for(register int i=fst[x];i;i=nxt[i])
    18 #define pb(i,x) vec[i].push_back(x)
    19 #define pls(a,b) (a+b)%MOD
    20 #define mns(a,b) (a-b+MOD)%MOD
    21 #define mul(a,b) (1LL*(a)*(b))%MOD
    22 using namespace std;
    23 inline int read()
    24 {
    25     int x=0,f=1;char ch=getchar();
    26     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    27     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 int n,m,rt[MAXN],ls[MAXN<<5],rs[MAXN<<5],rk[MAXN<<5],fa[MAXN<<5];
    31 int tot,las;
    32 void build(int &k,int l,int r)
    33 {
    34     k=++tot;if(l==r) {fa[k]=l;return ;}int mid=l+r>>1;
    35     build(ls[k],l,mid);build(rs[k],mid+1,r);
    36 }
    37 void mdf(int &k,int kk,int l,int r,int x,int pa)
    38 {
    39     k=++tot;if(l==r) {rk[k]=rk[kk],fa[k]=pa;return ;}int mid=l+r>>1;
    40     if(x<=mid) rs[k]=rs[kk],mdf(ls[k],ls[kk],l,mid,x,pa);
    41     else ls[k]=ls[kk],mdf(rs[k],rs[kk],mid+1,r,x,pa);
    42 }
    43 void add(int k,int l,int r,int x)
    44 {
    45     if(l==r) {rk[k]++;return ;}int mid=l+r>>1;
    46     x<=mid?add(ls[k],l,mid,x):add(rs[k],mid+1,r,x) ;
    47 }
    48 int query(int k,int l,int r,int x)
    49 {
    50     if(l==r) return k;int mid=l+r>>1;
    51     return x<=mid?query(ls[k],l,mid,x):query(rs[k],mid+1,r,x);
    52 }
    53 int find(int id,int x){int pos=query(rt[id],1,n,x);return x==fa[pos]?x:find(id,fa[pos]);}
    54 void merge(int id,int x,int y)
    55 {
    56     int f1=find(id,x),f2=find(id,y);if(f1==f2) return ;
    57     if(rk[f1]<rk[f2]) swap(f1,f2);mdf(rt[id],rt[id-1],1,n,f2,f1);
    58     if(rk[f1]==rk[f2]) add(rt[id],1,n,f1);
    59 }
    60 int main()
    61 {
    62     n=read(),m=read();build(rt[0],1,n);int c,a,b;
    63     rep(i,1,m)
    64     {
    65         c=read(),a=read()^las,rt[i]=rt[i-1];
    66         if(c==1) b=read()^las,merge(i,a,b);
    67         else if(c&1) b=read()^las,puts((las=(find(i,a)==find(i,b)))?"1":"0");
    68         else rt[i]=rt[a];
    69     }
    70 }
    View Code
  • 相关阅读:
    搞清楚C#中的值类型(基础类型)和引用类型
    构造动态SQL语句
    Json.net API及常用方法
    泛型代码中的default有何作用
    SQL 中的for xml path()的使用
    fastJosn和JackJson的区别
    箭头函数
    3篇文章初探MVC工作流程
    MVC传递Model之TempData、ViewData、ViewBag区别和用途
    .Net 提交页面,js修改的Label值会丢掉
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10544156.html
Copyright © 2011-2022 走看看