• 【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"));
    }
    
  • 相关阅读:
    十四、内部类
    十三、模板设计模式
    十二、面向对象之多态
    三、泛型
    Spring Security学习笔记
    Maven构建web项目在Eclipse中部署的几种方法
    spring如何实现定时任务
    安装jar包到本地仓库
    使用java对pdf转成tiff文件
    word文档转pdf解决修订问题
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145536.html
Copyright © 2020-2023  润新知