zoukankan      html  css  js  c++  java
  • loj121-动态图连通性

    Solution

    线段树分治, 然后直接在线段树上dfs, 在进入/回溯的过程中维护并查集的merge/split.

    对于split操作, 可以在merge时按秩合并, 然后利用栈记录, split时恢复即可.

    Code

    #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=5050,msz=5e5+50;
    int n,m;
    int edno[nsz][nsz],pe=0,pq=0,pq1=1;
    struct te{int f,t,l,r;}edge[msz];
    struct tq{int a,b,t,ans;}que[msz];
    
    int fa[nsz],dep[nsz];
    int stk[msz][2],top=0;//0 y; 1 dep[x]
    int find(int p){return p==fa[p]?p:find(fa[p]);}
    bool conn(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;
    	}
    }
    
    vector<int> ee[msz*4];
    #define ls(p) ((p)<<1)
    #define rs(p) ((p)<<1|1)
    void insert(int v,int l,int r,int rt,int rl,int rr){
    	if(l<=rl&&rr<=r){ee[rt].push_back(v);return;}
    	int mid=(rl+rr)>>1;
    	if(l<=mid)insert(v,l,r,ls(rt),rl,mid);
    	if(mid<r)insert(v,l,r,rs(rt),mid+1,rr);
    }
    void dfs(int rt,int rl,int rr){
    	int now=top;
    	for(int i:ee[rt])merge(edge[i].f,edge[i].t);
    	if(rl==rr){
    		while(pq1<=pq&&que[pq1].t==rl)que[pq1].ans=conn(que[pq1].a,que[pq1].b),++pq1;
    	}
    	else{
    		int mid=(rl+rr)>>1;
    		dfs(ls(rt),rl,mid);
    		dfs(rs(rt),mid+1,rr);
    	}
    	del(now);
    }
    
    int main(){
    //	freopen("a.in","r",stdin);
    //	freopen("a.out","w",stdout);
    	ios::sync_with_stdio(0),cin.tie(0);
    	cin>>n>>m;
    	int a,b,c;
    	rep(i,1,m){
    		cin>>a>>b>>c;
    		if(b>c)swap(b,c);
    		if(a==0){
    			edge[++pe]=(te){b,c,i,m};
    			edno[b][c]=pe;
    		}
    		else if(a==1){
    			edge[edno[b][c]].r=i;
    		}
    		else{
    			que[++pq]=(tq){b,c,i,0};
    		}
    	}
    	rep(i,1,n)fa[i]=i,dep[i]=1;
    	rep(i,1,pe)insert(i,edge[i].l,edge[i].r,1,1,m);
    	dfs(1,1,m);
    	rep(i,1,pq){cout<<(que[i].ans?"Y":"N")<<'
    ';}
    	return 0;
    }
    
  • 相关阅读:
    机器学习--决策树
    插入排序、选择排序的实现与性能比较
    【笔记】如何实现属性可修改的函数装饰器
    【笔记】如何为被装饰的函数保存元数据
    【笔记】对文件的一些操作
    【笔记】对字符串的一些操作
    USB鼠标按键驱动
    LCD驱动 15-3
    LCD驱动 15 -2
    LCD驱动 15-1
  • 原文地址:https://www.cnblogs.com/ubospica/p/10608486.html
Copyright © 2011-2022 走看看