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")<<'\n';}
	return 0;
}
posted @ 2019-03-27 16:28  Ubospica  阅读(336)  评论(0编辑  收藏  举报