zoukankan      html  css  js  c++  java
  • 【BZOJ】3673: 可持久化并查集 by zky & 3674: 可持久化并查集加强版(可持久化线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3674

    http://www.lydsy.com/JudgeOnline/problem.php?id=3673

    双倍经验啦啦啦。。

    给主席树换了个名称果然高大上。。。

    首先要可持久化并查集其实就是可持久化数组。。。

    那么因为数组的形式是这样的$P[x]$,那么我们用一种数据结构实现查找x返回对应的$P[x]$即可啦啦啦。

    然后那么我所学的可持久化目前只有主席树QAQ哪天去写写fhqtreap。。。

    所以用主席树查找下标x,然后在叶子中维护父亲。

    然后就完了

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    #include <ext/rope>
    using namespace std;
    typedef long long ll;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << (#x) << " = " << (x) << endl
    #define error(x) (!(x)?puts("error"):0)
    #define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    
    const int N=2*1e5+10;
    struct node { int l, r, f; }t[N*100];
    int cnt, root[N], n;
    
    void update(int l, int r, int &x, int pos, int f) {
    	t[++cnt]=t[x]; x=cnt;
    	if(l==r) { t[x].f=f; return; }
    	int mid=(l+r)>>1;
    	if(pos<=mid) update(l, mid, t[x].l, pos, f);
    	else update(mid+1, r, t[x].r, pos, f);
    }
    int ask(int l, int r, int x, int pos) {
    	if(l==r) return t[x].f;
    	int mid=(l+r)>>1;
    	if(pos<=mid) return ask(l, mid, t[x].l, pos);
    	else return ask(mid+1, r, t[x].r, pos);
    }
    int P(int x, int y) { return ask(1, n, x, y); }
    int un(int &x, int a, int b) { update(1, n, x, a, b); return b; } // union p(a)=y
    int find(int &x, int y) { int f=P(x, y); return f==y?y:un(x, y, find(x, f)); }
    int main() {
    	read(n); int m=getint(), la=0;
    	for1(i, 1, n) update(1, n, root[0], i, i);
    	for1(i, 1, m) {
    		int c=getint();
    		root[i]=root[i-1];
    		if(c==1) {
    			int x=getint(), y=getint(); x^=la; y^=la;
    			int fx=find(root[i], x), fy=find(root[i], y);
    			if(fx!=fy) un(root[i], fx, fy);
    		}
    		else if(c==2) root[i]=root[getint()^la];
    		else {
    			int x=getint(), y=getint(); x^=la; y^=la;
    			int fx=find(root[i], x), fy=find(root[i], y);
    			printf("%d
    ", la=(fx==fy));
    		}
    	}
    	return 0;
    }
    

      


    Description

    Description:
    自从zkysb出了可持久化并查集后……
    hzwer:乱写能AC,暴力踩标程
    KuribohG:我不路径压缩就过了!
    ndsf:暴力就可以轻松虐!
    zky:……

    n个集合 m个操作
    操作:
    1 a b 合并a,b所在集合
    2 k 回到第k次操作之后的状态(查询算作操作)
    3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
    请注意本题采用强制在线,所给的a,b,k均经过加密,加密方法为x = x xor lastans,lastans的初始值为0
    0<n,m<=2*10^5


    Input

     

    Output

     

    Sample Input

    5 6
    1 1 2
    3 1 2
    2 1
    3 0 3
    2 1
    3 1 2

    Sample Output

    1
    0
    1

    HINT

     

    Source

  • 相关阅读:
    linux date使用
    SHELL输出带颜色字体
    vimrc配置
    你所不知道的C++
    temp
    说什么好呢3
    Extjs3 Combo实现百度搜索查询
    Extjs3笔记 fbar
    Extjs combo赋值与刷新的先后顺序
    sql中nvarchar(max)长度测试
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4151710.html
Copyright © 2011-2022 走看看