传送门
解析:
真的,这道题的算法就只有树上倍增,但是考场上还是考虑打暴力吧(AK大佬请无视)。。。
毕竟还是太难码了QAQ。
思路:
其实标准题解已经说的很清楚了。。。而且这个解析真要写起来差不多就是代码那么难写,所以要问我的挑个我没忙的时间来问吧。。。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
#define cerr cout
inline int getint(){
re int num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
inline void outint(int a){
static char ch[13];
if(a==0)pc('0');
while(a)ch[++ch[0]]=a-a/10*10,a/=10;
while(ch[0])pc(ch[ch[0]--]^48);
}
inline char getalpha(){
re char c;
while(!isalpha(c=gc()));
return c;
}
cs int N=200005,logN=20;
int last[N],nxt[N<<1],to[N<<1],ecnt;
inline void addedge(int u,int v){
nxt[++ecnt]=last[u],last[u]=ecnt,to[ecnt]=v;
nxt[++ecnt]=last[v],last[v]=ecnt,to[ecnt]=u;
}
int fa[N][logN+1],maxn[N][3],son[N][3],dep[N],in[N],out[N],idx;
int fans[N][logN+1][2];
inline void dfs1(int u){
in[u]=++idx;
for(int re i=1;i<=logN;++i)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]]){
if(v==fa[u][0])continue;
dep[v]=dep[u]+1;
fa[v][0]=u;
dfs1(v);
if(maxn[v][0]+1>maxn[u][0]){
son[u][2]=son[u][1];son[u][1]=son[u][0];son[u][0]=v;
maxn[u][2]=maxn[u][1];maxn[u][1]=maxn[u][0];maxn[u][0]=maxn[v][0]+1;
}
else if(maxn[v][0]+1>maxn[u][1]){
son[u][2]=son[u][1];son[u][1]=v;
maxn[u][2]=maxn[u][1];maxn[u][1]=maxn[v][0]+1;
}
else if(maxn[v][0]+1>maxn[u][2]){
son[u][2]=v;
maxn[u][2]=maxn[v][0]+1;
}
}
out[u]=idx;
}
inline void dfs2(int u){
if(u^1){
fans[u][0][0]=(son[fa[u][0]][0]==u)?(maxn[fa[u][0]][1]+1):(maxn[fa[u][0]][0]+1);
fans[u][0][1]=(son[fa[u][0]][0]==u)?(maxn[fa[u][0]][1]+dep[fa[u][0]]):(maxn[fa[u][0]][0]+dep[fa[u][0]]);
}
for(int re i=1;i<=logN;++i){
fans[u][i][0]=max(fans[u][i-1][0],fans[fa[u][i-1]][i-1][0]+dep[u]-dep[fa[u][i-1]]);
fans[u][i][1]=max(fans[u][i-1][1],fans[fa[u][i-1]][i-1][1]);
}
for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]]){
if(v==fa[u][0])continue;
dfs2(v);
}
}
inline int jump(int u,int step){
for(int re i=logN;~i;--i){
if((1<<i)&step){
step-=1<<i;
u=fa[u][i];
}
}
return u;
}
inline int LCA(int u,int v){
if(dep[u]<dep[v])swap(u,v);
if(dep[u]>dep[v])u=jump(u,dep[u]-dep[v]);
if(u==v)return u;
for(int re i=logN;~i;--i){
if(fa[u][i]!=fa[v][i])
u=fa[u][i],v=fa[v][i];
}
return fa[u][0];
}
inline int queryin(int u,int v){
int res=fans[u][logN][0];
for(int re i=logN;~i;--i){
if(dep[fa[v][i]]>dep[u]){
res=max(res,fans[v][i][1]-dep[u]);
v=fa[v][i];
}
}
if(son[u][0]!=v)res=max(res,maxn[u][0]);
else if(son[u][1]!=v)res=max(res,maxn[u][1]);
else res=max(res,maxn[u][2]);
return res;
}
inline int queryout(int u,int v){
int lca=LCA(u,v),o=u,ans=maxn[u][0];
for(int re i=logN;~i;--i){
if(dep[fa[u][i]]>dep[lca]){
ans=max(ans,fans[u][i][0]-dep[u]+dep[o]);
u=fa[u][i];
}
if(dep[fa[v][i]]>dep[lca]){
ans=max(ans,fans[v][i][1]-dep[lca]*2+dep[o]);
v=fa[v][i];
}
}
if(son[lca][0]!=u&&son[lca][0]!=v)ans=max(ans,maxn[lca][0]+dep[o]-dep[lca]);
else if(son[lca][1]!=u&&son[lca][1]!=v)ans=max(ans,maxn[lca][1]+dep[o]-dep[lca]);
else ans=max(ans,maxn[lca][2]+dep[o]-dep[lca]);
if(lca!=v)ans=max(ans,dep[o]-dep[lca]+fans[lca][logN][0]);
return ans;
}
int n,m,root;
signed main(){
n=getint();
root=1;
for(int re i=1;i<n;++i){
int u=getint(),v=getint();
addedge(u,v);
}
fa[1][0]=1;dep[1]=1;
dfs1(1),dfs2(1);
m=getint();
while(m--){
switch(getalpha()){
case 'C':{
root=getint();
break;
}
case 'Q':{
int u=getint(),dist=getint(),v;
int lca=LCA(u,root);
if(dist>dep[u]+dep[root]-2*dep[lca]){
outint(max(maxn[u][0],fans[u][logN][0]));pc('\n');
break;
}
if(dist<=dep[u]-dep[lca])v=jump(u,dist-1);
else v=jump(root,dep[root]-2*dep[lca]+dep[u]-dist);
if(in[u]<in[v]&&out[u]>=in[v]){
outint(queryin(u,v));
pc('\n');
}
else{
outint(queryout(u,v));
pc('\n');
}
break;
}
}
}
return 0;
}