0分 RE 和 WA 参半
#include <bits/stdc++.h>
using namespace std;
#define lson x<<1
#define rson x<<1|1
int n,m,Q,fa[30010],fat[30010],siz[30010],deep[30010],id[30010],idx,top[30010],son[30010],col;
map<int,bool> mp[30010];
pair<int,int> g[100010];
struct Node{
int op,u,v;
}qry[40010];
int ans[40010],cn;
vector<int> ed[30010];
bool vis[100010];
struct Tree{
int val,clo,cro,b;
}tree[120010];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void dfs1(int x,int fa){
int len=ed[x].size();
fat[x]=fa;deep[x]=deep[fa]+1;siz[x]=1;
for(int i=0;i<len;i++){
int v=ed[x][i];
if(v==fa) continue;
dfs1(v,x);
siz[x]+=siz[v];
if(siz[v]>siz[son[x]]) son[x]=v;
}
}
void dfs2(int x,int t){
int len=ed[x].size();
top[x]=t;
id[x]=++idx;
if(son[x]) dfs2(son[x],t);
for(int i=0;i<len;i++){
int v=ed[x][i];
if(v==fat[x]||v==son[x]) continue;
dfs2(v,v);
}
}
void update(int x,int l,int r,int cl,int cr,int d){
if(cl<=l&&r<=cr){
tree[x]={0,d,d,d};
return;
}
int mid=(l+r)>>1;
if(tree[x].b){
tree[lson]=tree[rson]={0,tree[x].b,tree[x].b,tree[x].b};
tree[x].b=0;
}
if(mid>=cl) update(lson,l,mid,cl,cr,d);
if(mid<cr) update(rson,mid+1,r,cl,cr,d);
tree[x].clo=tree[lson].clo;tree[x].cro=tree[rson].cro;
tree[x].val=tree[lson].val+tree[rson].val+(tree[lson].cro!=tree[rson].clo);
}
Tree query(int x,int l,int r,int cl,int cr){
if(cl<=l&&r<=cr) return tree[x];
if(tree[x].b){
tree[lson]=tree[rson]={0,tree[x].b,tree[x].b,tree[x].b};
tree[x].b=0;
}
int mid=(l+r)>>1;
Tree ans;
if(mid>=cl) ans=query(lson,l,mid,cl,cr);
if(mid<cr){
if(mid>=cl){
Tree ces=query(rson,mid+1,r,cl,cr);
ans.val+=ces.val+(ans.cro!=ces.clo);
ans.cro=ces.cro;
}else ans=query(rson,mid+1,r,cl,cr);
}
return ans;
}
void build(int x,int l,int r){
if(l==r){
tree[x].clo=tree[x].cro=++col;
tree[x].val=0;
return;
}
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
tree[x].val=tree[lson].val+tree[rson].val+(tree[lson].cro!=tree[rson].clo);
tree[x].clo=tree[lson].clo;tree[x].cro=tree[rson].cro;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++) scanf("%d%d",&g[i].first,&g[i].second);
while(~scanf("%d",&qry[++Q].op)){
if(qry[Q].op==-1) break;
scanf("%d%d",&qry[Q].u,&qry[Q].v);
mp[qry[Q].u][qry[Q].v]=1;
}
Q--;
for(int i=1;i<=m;i++){
int u=g[i].first,v=g[i].second;
if(mp[u][v]||mp[v][u]){vis[i]=1;continue;}
int fu=find(u),fv=find(v);
if(fu==fv) continue;
vis[i]=1;
fa[fu]=fv;
ed[u].push_back(v);
ed[v].push_back(u);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
for(int i=1;i<=m;i++){
if(vis[i]) continue;
col++;
int u=g[i].first,v=g[i].second;
while(top[u]!=top[v]){
if(deep[top[u]]<deep[top[v]]) swap(u,v);
update(1,1,n,id[top[u]],id[u],col);
u=fat[top[u]];
}
if(deep[u]<deep[v]) swap(u,v);
update(1,1,n,id[v],id[u],col);
}
for(int i=Q;i>=1;i--){
int u=qry[i].u,v=qry[i].v;
if(!qry[i].op){
col++;
while(top[u]!=top[v]){
if(deep[top[u]]<deep[top[v]]) swap(u,v);
update(1,1,n,id[top[u]],id[u],col);
u=fat[top[u]];
}
if(deep[u]<deep[v]) swap(u,v);
update(1,1,n,id[v],id[u],col);
}else{
cn++;
while(top[u]!=top[v]){
if(deep[top[u]]<deep[top[v]]) swap(u,v);
Tree as1=query(1,1,n,id[top[u]],id[u]);
ans[cn]+=as1.val;
u=fat[top[u]];
Tree as2=query(1,1,n,id[u],id[u]);
ans[cn]+=(as1.clo!=as2.cro);
}
if(deep[u]<deep[v]) swap(u,v);
Tree as=query(1,1,n,id[v],id[u]);
ans[cn]+=as.val;
}
}
for(int i=cn;i>=1;i--) printf("%d\n",ans[i]);
return 0;
}