【LOJ#121】—「离线可过」动态图连通性(线段树分治)
把一条边的存在时间映射到询问时间上
用个伪的线段树分治存一下
最后一次回答所有询问就行了
要撤销并查集就启发式合并优化
#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"));
}