【LOJ#121】—「离线可过」动态图连通性(线段树分治)

传送门


把一条边的存在时间映射到询问时间上
用个伪的线段树分治存一下
最后dfsdfs一次回答所有询问就行了

要撤销并查集就启发式合并优化

#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
	static char ibuf[RLEN],*ib,*ob;
	(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob)?EOF:*ib++;
}
#define gc getchar
inline int read(){
	char ch=gc();
	int res=0,f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
	return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
const int N=5005,M=500005;
int n,m,tot,ans[M];
vector<pii> e[M<<2];
map<pii,int> ti;
struct ask{
	int u,v,id;
	ask(int _u,int _v,int _id):u(_u),v(_v),id(_id){}
};
vector<ask> q[M<<2];
int siz[N],fa[N],top;
pii stk[N];
inline int find(int x){
	while(x!=fa[x])x=fa[x];return x;
}
inline void merge(pii x){
	int f1=find(x.fi),f2=find(x.se);
	if(f1==f2)return;
	if(siz[f1]>siz[f2])swap(f1,f2);
	fa[f1]=f2,siz[f2]+=siz[f1];
	stk[++top]=pii(f1,f2);
}
inline void delet(pii x){
	int f1=x.fi,f2=x.se;
	fa[f1]=f1,siz[f2]-=siz[f1];
}
#define lc (u<<1)
#define rc ((u<<1)|1)
#define mid ((l+r)>>1)
void update(int u,int l,int r,int st,int des,pii k){
	if(st<=l&&r<=des){e[u].pb(k);return;}
	if(st<=mid)update(lc,l,mid,st,des,k);
	if(mid<des)update(rc,mid+1,r,st,des,k);
}
void dfs(int u,int l,int r){
	int pre=top;
	if(l==r){
		for(auto &x:e[u])
			merge(x);
		for(auto &x:q[l]){
			if(find(x.u)==find(x.v))ans[x.id]=1;
			else ans[x.id]=0;
		}
		while(top>pre)delet(stk[top--]);
		return;
	}
	for(auto &x:e[u])merge(x);
	dfs(lc,l,mid),dfs(rc,mid+1,r);
	while(top>pre)delet(stk[top--]);
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++)fa[i]=i,siz[i]=1;
	for(int i=1;i<=m;i++){
		int op=read(),u=read(),v=read();
		if(u>v)swap(u,v);
		if(op==0)
			ti[pii(u,v)]=i;
		if(op==1){
			int pos=ti[pii(u,v)];ti.erase(pii(u,v));
			update(1,1,m,pos,i,pii(u,v));
		}
		if(op==2)
			q[i].pb(ask(u,v,++tot));
	}
	for(auto &p:ti){
		update(1,1,m,p.se,m,p.fi);
	}
	dfs(1,1,m);
	for(int i=1;i<=tot;i++)(ans[i])?(puts("Y")):(puts("N"));
}
原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145536.html