神题,看着别人代码学习
#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;
}