解析
倍增真香
关键性质:树上距离一个点最远的点必定是直径两端点其一。
本题限制好,要求少动态维护倍增数组暴力维护直径即可。
如果每次合并的是两棵树,而不是一棵树加一个点,可以先离线下来,照样能做。
如果每次强制在线,用LCT算距离即可(split出来后splay大小减1)。
如果还要支持删边,需要维护一个
f
x
f_x
fx 表示
x
x
x 的splay子树内深度最浅的结点真实子树内深度最大的结点深度。(深度均指真实深度)
转移:
f
l
s
x
→
f
x
f_{ls_x}\to f_x
flsx→fx
s
i
z
l
s
x
+
f
r
s
x
→
f
x
siz_{ls_x}+f_{rs_x}\to f_x
sizlsx+frsx→fx
f
l
s
x
+
h
e
a
p
x
.
t
o
p
(
)
→
f
x
f_{ls_x}+heap_x.top()\to f_x
flsx+heapx.top()→fx
最后一个是用堆维护虚子树内所有的
f
s
o
n
f_{son}
fson,然后用最大的堆顶转移。
为了支持
r
e
v
e
r
s
e
reverse
reverse 操作,还需要维护一个
g
x
g_x
gx 表示
x
x
x 的splay子树内深度最深的结点往上延伸深度最大的结点深度,把转移式所有左右儿子互换即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){
ll x(0),f(1);char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
const int N=1e5+100;
const int M=2e4+100;
const int inf=1e9;
int n,tot;
int pl[N][20],dep[N];
int fa[N],u[N],v[N],d[N];
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
char c;
int x;
inline int Lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int k=17;k>=0;k--){
if(dep[pl[x][k]]>=dep[y]) x=pl[x][k];
}
if(x==y) return x;
for(int k=17;k>=0;k--){
if(pl[x][k]==pl[y][k]) continue;
x=pl[x][k];y=pl[y][k];
}
return pl[x][0];
}
inline int dis(int x,int y){
int lca=Lca(x,y);
return dep[x]+dep[y]-2*dep[lca];
}
signed main(){
#ifndef ONLINE_JUDGE
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
#endif
n=read();
while(n--){
scanf(" %c%d",&c,&x);
if(c=='B'){
int now=++tot;
if(x==-1) x=0;
pl[now][0]=x;
for(int k=1;pl[now][k-1];++k) pl[now][k]=pl[pl[now][k-1]][k-1];
dep[now]=dep[x]+1;
if(x){
int o=find(x),tmp(0);
fa[now]=o;
if((tmp=dis(now,u[o]))>d[o]){
v[o]=now;d[o]=tmp;
}
if((tmp=dis(now,v[o]))>d[o]){
u[o]=now;d[o]=tmp;
}
}
else{
fa[now]=now;u[now]=v[now]=now;d[now]=0;
}
}
else{
int o=find(x);
printf("%d\n",max(dis(u[o],x),dis(v[o],x)));
}
}
return 0;
}
/*
10 10
1 8 5
1 6 5
1 7 9
1 4 2
1 3 4
1 4 2
1 6 3
1 4 1
1 7 1
1 8 4
*/