神题,看着别人代码学习
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<string> #include<iomanip> #include<vector> #include<set> #include<map> #include<queue> using namespace std; typedef long long LL; typedef unsigned long long ULL; #define rep(i,k,n) for(int i=(k);i<=(n);i++) #define rep0(i,n) for(int i=0;i<(n);i++) #define red(i,k,n) for(int i=(k);i>=(n);i--) #define sqr(x) ((x)*(x)) #define clr(x,y) memset((x),(y),sizeof(x)) #define pb push_back #define mod 1000000007 const int maxn=30010; const int maxq=100010; const int N=15; int n,m,q; int fa[maxn][N]; int beg[maxn],ed[maxn],dtime,dep[maxn],ans[maxq]; struct edge { int to,del; edge(int x):to(x),del(0){} bool operator < (const edge &x) const { if(to!=x.to)return to<x.to; return del>x.del; } }; vector<edge> e[maxn]; struct QUERY { int op,u,v; void read() { scanf("%d%d%d",&op,&u,&v); if(op==1) { lower_bound(e[u].begin(),e[u].end(),edge(v))->del=1; lower_bound(e[v].begin(),e[v].end(),edge(u))->del=1; } } }Q[maxq]; struct BIT { int v[maxn]; void init() { clr(v,0); } void add(int x,int k) { for(;x<=n;x+=x&-x)v[x]+=k; } void update(int L,int R,int k) { add(L,k); add(R+1,-k); } int qry(int x) { int ret=0; for(;x;x-=x&-x)ret+=v[x]; return ret; } }B; void dfs(int u,int F,int deep) { if(F)e[u].erase(lower_bound(e[u].begin(),e[u].end(),edge(F))); beg[u]=++dtime; dep[u]=deep; fa[u][0]=F; for(int i=0;i<e[u].size();i++) { if(e[u][i].del || beg[e[u][i].to])continue; e[u][i].del=1; dfs(e[u][i].to,u,deep+1); } ed[u]=dtime; B.update(beg[u],ed[u],1); } void Lca_init() { for(int i=1;i<N;i++)rep(j,1,n)fa[j][i]=fa[fa[j][i-1]][i-1]; } int lca(int u,int v) { if(dep[u]<dep[v])swap(u,v); int t=dep[u]-dep[v]; for(int i=0;i<N;i++)if((1<<i)&t)u=fa[u][i]; if(u==v)return u; for(int i=N-1;i>=0;i--) { if(fa[u][i]!=fa[v][i]) { u=fa[u][i]; v=fa[v][i]; } } return fa[u][0]; } struct UNION { int f[maxn]; void init() { rep(i,1,n)f[i]=i; rep(i,1,n)for(int j=0;j<e[i].size();j++) { if(e[i][j].del)continue; merge(i,e[i][j].to); } } int getf(int x) { return x==f[x]?x:f[x]=getf(f[x]); } void mergef(int u,int ff) { while(u!=ff) { int t=getf(fa[u][0]); f[u]=t; B.update(beg[u],ed[u],-1); u=t; } } void merge(int u,int v) { u=getf(u); v=getf(v); int ff=getf(lca(u,v)); mergef(u,ff); mergef(v,ff); } }U; void solve() { clr(beg,0);clr(ed,0); B.init(); dtime=0; dfs(1,0,1); Lca_init(); U.init(); int tot=0; red(i,q,1) { int u=U.getf(Q[i].u),v=U.getf(Q[i].v); if(Q[i].op==1) { U.merge(u,v); } else { int ff=U.getf(lca(u,v)); ans[++tot]=B.qry(beg[u])+B.qry(beg[v])-2*B.qry(beg[ff]); } } red(i,tot,1)printf("%d\n",ans[i]); } int main() { int T; scanf("%d",&T); rep(ii,1,T) { printf("Case #%d:\n",ii); scanf("%d%d%d",&n,&m,&q); rep(i,1,n)e[i].clear(); rep(i,1,m) { int u,v; scanf("%d%d",&u,&v); e[u].pb(edge(v)); e[v].pb(edge(u)); } rep(i,1,n)sort(e[i].begin(),e[i].end()); rep(i,1,q)Q[i].read(); solve(); } return 0; }