• bzoj3673-可持久化并查集


    Description

    BZOJ

    Solution

    并不要求在线, 然后就有很优秀 好写 的离线做法...

    我们考虑把每个操作建成一个点 (i).

    对于 (1)(3) 操作, 连边 ((i-1, i));

    对于 (2) 操作, 连边 ((k_i, i)).

    容易发现这是一棵树, 并且并查集的操作可以回退, 那么我们直接在树上dfs, 在进入节点/回溯时处理merge/split/查询即可.

    时间复杂度 (O(m log n))

    代码超短...

    Code

    #pragma GCC diagnostic error "-std=c++11"
    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    using namespace std;
    #define rep(i,l,r) for(register int i=(l);i<=(r);++i)
    #define repdo(i,l,r) for(register int i=(l);i>=(r);--i)
    #define il inline
    typedef double db;
    typedef long long ll;
    
    //---------------------------------------
    const int nsz=2e4+50;
    int n,m,ans[nsz],las;
    
    int fa[nsz],dep[nsz];
    int stk[nsz][2],top=0;
    void init(){rep(i,1,n)fa[i]=i,dep[i]=1;}
    int find(int p){return p==fa[p]?p:find(fa[p]);}
    int iscon(int a,int b){return find(a)==find(b);}
    void merge(int a,int b){
    	a=find(a),b=find(b);
    	if(a==b)return;
    	if(dep[a]<dep[b])swap(a,b);
    	stk[++top][0]=b,stk[top][1]=dep[a];
    	fa[b]=a,dep[a]=max(dep[a],dep[b]+1);
    }
    void del(int top1){
    	for(;top!=top1;--top){
    		int a=stk[top][0],b=stk[top][1];
    		dep[fa[a]]=b,fa[a]=a;
    	}
    }
    
    
    struct tqu{int ty,a,b;}qu[nsz];
    vector<int> ed[nsz];
    void adde(int f,int t){ed[f].push_back(t);}
    
    void dfs(int p){
    	int top1=top;
    	if(qu[p].ty==1)merge(qu[p].a,qu[p].b);
    	else if(qu[p].ty==3)ans[p]=iscon(qu[p].a,qu[p].b);
    	for(int v:ed[p]){
    		dfs(v);
    	}
    	del(top1);
    }
    
    int main(){
    	ios::sync_with_stdio(0),cin.tie(0);
    	cin>>n>>m;
    	init();
    	int a,b,c;
    	rep(i,1,m){
    		cin>>a>>b,qu[i].ty=a,qu[i].a=b;
    		if(a==2)adde(b,i);
    		else cin>>c,qu[i].b=c,adde(las,i);
    		las=i;
    	}
    	dfs(0);
    	rep(i,1,m)if(qu[i].ty==3)cout<<ans[i]<<'
    ';
    	return 0;
    }
    
  • 相关阅读:
    返回一个整数数组中最大子数组的和(数组头尾连接)
    场景调研(补)
    《浪潮之巅》读书笔记3
    《软件工程》课程改进意见
    【每日scrum】第一次冲刺day6
    【每日scrum】第一次冲刺day5
    【每日scrum】第一次冲刺day4
    【每日scrum】第一次冲刺day3
    【每日scrum】第一次冲刺day2
    【每日scrum】第一次冲刺day1
  • 原文地址:https://www.cnblogs.com/ubospica/p/10645546.html
Copyright © 2020-2023  润新知