rt,悬关。
离线做法,代码如下
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e4+10,maxm=1e5+10,maxq=4e4+10;
int n,m,cnt=0,tt,dfn,anstot,f[maxn],ans[maxq],head[maxn],son[maxn],siz[maxn],val[maxn],wv[maxn],id[maxn],dep[maxn],fa[maxn],tp[maxn];
bool vis[maxm];
map< pair<int,int>,bool > ava;
pair<int,int> e1[maxm];
struct edge{
int u,v,w,nxt;
}e[maxm];
struct data{
int typ,u,v;
}q[maxq];
struct TREE{
int sum,tag;
}t[maxn<<2];
int find(int u){
if(u==f[u]) return u;
return f[u]=find(f[u]);
}
#define ls(k) k<<1
#define rs(k) k<<1|1
void pushup(int k){
t[k].sum=t[ls(k)].sum+t[rs(k)].sum;
}
void pushdown(int k){
if(t[k].tag!=-1){
t[ls(k)].sum=t[rs(k)].sum=t[ls(k)].tag=t[rs(k)].tag=0;
t[k].tag=-1;
}
}
void build(int k,int l,int r){
t[k].tag=-1;
if(l==r){
t[k].sum=wv[l];
return;
}
int mid=(l+r)>>1;
build(ls(k),l,mid);
build(rs(k),mid+1,r);
pushup(k);
}
void upd(int k,int l,int r,int ql,int qr){
if(ql>qr) return;
pushdown(k);
if(ql<=l&&r<=qr){
t[k].sum=t[k].tag=0;
return;
}
int mid=(l+r)>>1;
if(ql<=mid) upd(ls(k),l,mid,ql,qr);
if(mid<qr) upd(rs(k),mid+1,r,ql,qr);
pushup(k);
}
int query(int k,int l,int r,int ql,int qr){
if(ql>qr) return 0;
pushdown(k);
if(ql<=l&&r<=qr) return t[k].sum;
int mid=(l+r)>>1,res=0;
if(ql<=mid) res+=query(ls(k),l,mid,ql,qr);
if(mid<qr) res+=query(rs(k),mid+1,r,ql,qr);
return res;
}
inline void add(int u,int v){
e[++tt].u=u;
e[tt].v=v;
e[tt].w=1;
e[tt].nxt=head[u];
head[u]=tt;
}
void dfs1(int u,int ff,int w){
fa[u]=ff;
dep[u]=dep[ff]+1;
son[u]=-1;
siz[u]=1;
val[u]=w;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==ff) continue;
dfs1(v,u,e[i].w);
siz[u]+=siz[v];
if(son[u]==-1||siz[son[u]]<siz[v]) son[u]=v;
}
}
void dfs2(int u,int p){
tp[u]=p;
id[u]=++dfn;
wv[dfn]=val[u];
if(son[u]==-1) return;
dfs2(son[u],p);
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
void updline(int u,int v){
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
upd(1,1,dfn,id[tp[u]],id[u]);
u=fa[tp[u]];
}
if(dep[u]>dep[v]) swap(u,v);
upd(1,1,dfn,id[u]+1,id[v]);
}
int qline(int u,int v){
int res=0;
while(tp[u]!=tp[v]){
if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
res+=query(1,1,dfn,id[tp[u]],id[u]);
u=fa[tp[u]];
}
if(dep[u]>dep[v]) swap(u,v);
res+=query(1,1,dfn,id[u]+1,id[v]);
return res;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
int u,v;
scanf("%d%d",&u,&v);
e1[i]=make_pair(u,v);
}
for(int i=1;i<=n;++i) f[i]=i;
while(true){
int op,u,v;
scanf("%d",&op);
if(op==-1) break;
scanf("%d%d",&u,&v);
q[++cnt]=(data){op,u,v};
if(!op) ava[make_pair(u,v)]=ava[make_pair(v,u)]=1;
}
for(int i=1;i<=m;++i){
int u=e1[i].first,v=e1[i].second;
int fu=find(u),fv=find(v);
if(!ava[make_pair(u,v)]&&fu!=fv){
add(u,v),add(v,u);
f[fu]=fv;
vis[i]=true;
}
}
dfs1(1,0,0);
dfs2(1,1);
build(1,1,n);
for(int i=1;i<=m;++i){
int u=e1[i].first,v=e1[i].second;
if(!vis[i]&&!ava[make_pair(u,v)]) updline(u,v);
}
for(int i=cnt;i>=1;--i){
if(q[i].typ) ans[++anstot]=qline(q[i].u,q[i].v);
else updline(q[i].u,q[i].v);
}
for(int i=anstot;i>=1;--i) printf("%d\n",ans[i]);
return 0;
}