zoukankan      html  css  js  c++  java
  • [bzoj] 3673 3674 可持久化并查集 || 可持久化数组

    原题

    加强版

    题意:
    可持久化并查集模板……

    题解:
    用可持久化线段树维护一个可持久化数组,来记录每一次操作后的状态。
    不能用路径压缩,但是要按置合并,使复杂度保证在O(log)

    #include<cstdio>
    #include<algorithm>
    #define N 200010
    #define M 5000010
    using namespace std;
    int n,m,f[N],root[N],cnt,sze[M];
    struct hhh
    {
        int ls,rs,sum;
    }tre[M];
    
    int read()
    {
        int ans=0,fu=1;
        char j=getchar();
        for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
        for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
        return ans*fu;
    }
    
    void change(int &now,int old,int l,int r,int x,int y)
    {
        now=++cnt;
        tre[now].rs=tre[old].rs;
        tre[now].ls=tre[old].ls;
        if (l==r) return (void)(tre[now].sum=y);
        int mid=(l+r)>>1;
        if (x>mid) change(tre[now].rs,tre[old].rs,mid+1,r,x,y);
        else change(tre[now].ls,tre[old].ls,l,mid,x,y);
    }
    
    void add(int &i,int old,int l,int r,int pos)
    {
        i=++cnt;
        tre[i].ls=tre[old].ls;
        tre[i].rs=tre[old].rs;
        if (l==r) return (void)(sze[i]=sze[old]+1);
        int mid=(l+r)>>1;
        if (pos<=mid) add(tre[i].ls,tre[old].ls,l,mid,pos);
        else add(tre[i].rs,tre[old].rs,mid+1,r,pos);
    }
    
    int query(int i,int l,int r,int x)
    {
        if (!i) return x;
        if (l==r) return tre[i].sum?tre[i].sum:x;
        int mid=(l+r)>>1;
        if (x>mid) return query(tre[i].rs,mid+1,r,x);
        return query(tre[i].ls,l,mid,x);
    }
    
    int find(int now,int x)
    {
        int fa;
        while (1)
        {
    	fa=query(root[now],1,n,x);
    	if (x==fa) return x;
    	x=fa;
        }
    }
    
    int main()
    {
        n=read();m=read();
        int a,b,op,x,y;
        for (int i=1;i<=m;i++)
        {
    	op=read();a=read();
    	if (op==1)
    	{
    	    root[i]=root[i-1];
    	    b=read();
    	    x=find(i,a);y=find(i,b);
    	    if (x==y) continue;
    	    if (sze[x]>sze[y]) change(root[i],root[i],1,n,y,x);
    	    else change(root[i],root[i],1,n,x,y);
    	    if (sze[x]==sze[y]) add(root[i],root[i],1,n,y);
    	}
    	else if (op==2) root[i]=root[a];
    	else root[i]=root[i-1],b=read(),(find(i,a)==find(i,b))?puts("1"):puts("0");
        }
        return 0;
    }
    
  • 相关阅读:
    Release和Debug的区别[转]
    SVM运用到多分类[引]
    HMM
    [转] 数据挖掘 机器学习 模式识别的关系
    [转]mysql 数据导入
    java 获取当前时间戳
    二叉树遍历建树[zhuan]
    关于c指针[转]
    词法分析
    组合数据类型练习,综合练习
  • 原文地址:https://www.cnblogs.com/mrha/p/8657560.html
Copyright © 2011-2022 走看看