• 解题:洛谷3402 可持久化并查集


    题面

    滚下去补学考之前更一发

    基于可持久化线段树实现(我不很喜欢“主席树”这个名字),注意不能路径压缩,首先这与可持久化的思想冲突(即尽量利用之前已有的部分,只修改有修改的部分,路径压缩压完了岂不是gg),其次每次压缩还会有一个log的时间复杂度(查询),然后复杂度就是$O(nlog n)$的

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=100005;
     6 struct a
     7 {
     8     int bel,pst,siz;
     9 }aset[N*44];
    10 int root[N],son[N*44][2];
    11 int n,m,t1,t2,t3,tot,ans;
    12 int Create(int l,int r)
    13 {
    14     int nde=++tot;
    15     if(l==r)
    16         aset[nde]=(a){l,l,1};
    17     else
    18     {
    19         int mid=(l+r)/2;
    20         son[nde][0]=Create(l,mid);
    21         son[nde][1]=Create(mid+1,r);
    22     }
    23     return nde;
    24 }
    25 int Insert(int pre,int l,int r,int pos,a task)
    26 {
    27     int nde=++tot;
    28     son[nde][0]=son[pre][0];
    29     son[nde][1]=son[pre][1];
    30     if(l<r)
    31     {
    32         int mid=(l+r)/2;
    33         if(pos<=mid)
    34             son[nde][0]=Insert(son[pre][0],l,mid,pos,task);
    35         else
    36             son[nde][1]=Insert(son[pre][1],mid+1,r,pos,task);
    37     }
    38     else aset[nde]=task;
    39     return nde;
    40 }
    41 a Query(int nde,int l,int r,int pos)
    42 {
    43     if(l==r) 
    44         return aset[nde];
    45     else 
    46     {
    47         int mid=(l+r)/2;
    48         if(pos<=mid) return Query(son[nde][0],l,mid,pos);
    49         else return Query(son[nde][1],mid+1,r,pos);
    50     }
    51 }
    52 int finda(int b,int x)
    53 {
    54     int f=Query(b,1,n,x).bel;
    55     return (f==x)?x:finda(b,f);
    56 }
    57 int main()
    58 {
    59     scanf("%d%d",&n,&m);
    60     root[0]=Create(1,n);
    61     for(int i=1;i<=m;i++)
    62     {
    63         scanf("%d%d",&t1,&t2);
    64         if(t1==1)
    65         {
    66             scanf("%d",&t3); root[i]=root[i-1];
    67             int f1=finda(root[i],t2),f2=finda(root[i],t3);
    68             a r1=Query(root[i],1,n,f1),r2=Query(root[i],1,n,f2);
    69             if(r1.bel!=r2.bel) 
    70             {
    71                 if(r1.siz<r2.siz) swap(r1,r2);
    72                 r1.siz+=r2.siz,r2.bel=r1.bel;
    73                 root[i]=Insert(root[i],1,n,r2.pst,r2);
    74                 root[i]=Insert(root[i],1,n,r1.pst,r1);
    75             }
    76         }
    77         else if(t1==2)
    78             root[i]=root[t2];
    79         else
    80         {
    81             scanf("%d",&t3),root[i]=root[i-1];
    82             printf("%d
    ",finda(root[i],t2)==finda(root[i],t3));
    83         } 
    84     }
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    Windows系统环境变量path优先级测试报告
    URI和URL的区别
    智能引导式报错(Class file name must end with .class)
    【Algorithm】冒泡排序
    【C语言】练习2-9
    【C语言】练习2-8
    【C语言】练习2-1
    【C语言】练习1-23
    【C语言】练习1-22
    【C语言】练习1-21
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9989412.html
Copyright © 2020-2023  润新知