动态点分治做法;
更新一个点只会影响一条log的链,信息用三个堆维护;
点分治作为复杂度保证
#include
#define rep(i,k,n) for(int i=k;i<=n;i++)
#define inf 0x7f7f7f7f
using namespace std;
const int N=100005;
struct heap{
priority_queue<int> A,B;
void push(int x){A.push(x);}
void erase(int x){B.push(x);}
void pop(){
while(B.size() && A.top()==B.top()){A.pop();B.pop();}
A.pop();
}
int top(){
while(B.size() && A.top()==B.top()){A.pop();B.pop();}
if(!A.size())return 0;
return A.top();
}
int size(){
return A.size()-B.size();
}
int step(){
if(size()<2)return 0;
int x=top();pop();
int y=top();push(x);
return y;
}
}A,B[N],C[N];
int head[N],s[N],vis[N],dep[N],fa[N],q[3*N][20],bin[20],Log[2000005],sum,size,tot=0,n,Q,dfn=0,pos[N],root,c[N],black;
struct E{int to,next;E(int to=0,int next=0):to(to),next(next){}}edge[3*N];
void add(int x,int y){
edge[++tot]=E(y,head[x]);head[x]=tot;
edge[++tot]=E(x,head[y]);head[y]=tot;
}
void dfs(int x,int f){
dep[x]=dep[f]+1;
q[++dfn][0]=dep[x];
pos[x]=dfn;
for(int i=head[x];i;i=edge[i].next){
int v=edge[i].to;
if(v!=f)dfs(v,x);
q[++dfn][0]=dep[x]; ////euler!每个结点出现其度数+1次;
}
}
void init(){
rep(i,1,19)rep(j,1,dfn-bin[i]+1)q[j][i]=min(q[j][i-1],q[j+bin[i-1]][i-1]);
}
inline int rmp(int x,int y){
x=pos[x],y=pos[y];if(x>y)swap(x,y);
int j=Log[y-x+1];
return min(q[x][j],q[y-bin[j]+1][j]);
}
int dist(int x,int y){
return dep[x]+dep[y]-2*rmp(x,y);
}
void getroot(int x,int f){
s[x]=1;int kk=0;
for(int i=head[x];i;i=edge[i].next){
int v=edge[i].to;
if(!vis[v] && v!=f)
{getroot(v,x);
kk=max(kk,s[v]);
s[x]+=s[v];
}
}
kk=max(kk,sum-s[x]);
if(kkx;}
}
void build(int x){vis[x]=1;
for(int i=head[x];i;i=edge[i].next){
int v=edge[i].to;
if(!vis[v]){
size=inf,sum=s[v];
getroot(v,x);
fa[root]=x;
build(root);
}
}
}
void turn_off(int u,int v){
if(u==v){
B[u].push(0);
if(B[u].size()==2)A.push(B[u].top());
}
if(!fa[u])return;
int f=fa[u],dis=dist(f,v),tmp=C[u].top(); //C中维护最长链+1
C[u].push(dis);
if(dis>tmp){
int mx=B[f].top()+B[f].step();int sb=B[f].size();
if(tmp)B[f].erase(tmp);
B[f].push(dis);
int nx=B[f].top()+B[f].step();
if(nx>mx){
if(sb>=2)A.erase(mx);
if(B[f].size()>=2)A.push(nx);
}
}
turn_off(f,v);
}
void turn_on(int u,int v){
if(u==v){
if(B[u].size()==2)A.erase(B[u].top());
B[u].erase(0);
}
if(!fa[u])return;
int f=fa[u],dis=dist(f,v);
int tmp=C[u].top();
C[u].erase(dis);
if(dis==tmp){
int mx=B[f].top()+B[f].step();
int sb=B[f].size();
B[f].erase(dis);
if(C[u].top())B[f].push(C[u].top());
int nx=B[f].top()+B[f].step();
if(nxif(sb>=2)A.erase(mx);
if(B[f].size()>=2)A.push(nx);
}
}
turn_on(f,v);
}
int main(){
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
scanf("%d",&n);
int x,y;
rep(i,1,n-1){scanf("%d%d",&x,&y);add(x,y);}
bin[0]=1;rep(i,1,19)bin[i]=bin[i-1]<<1;
Log[0]=-1;rep(i,1,2000000)Log[i]=Log[i>>1]+1;
dfs(1,0);init();
size=inf,sum=n;
getroot(1,0);
build(root);
rep(i,1,n)
{c[i]=1,C[i].push(0);}
rep(i,1,n)
turn_off(i,i);
black=n;
scanf("%d",&Q);char ss[20];
while(Q--){
scanf("%s",ss);
if(ss[0]=='C'){
scanf("%d",&x);
if(c[x]){turn_on(x,x),black--;}
else turn_off(x,x),black++;
c[x]^=1;
}
else{
if(black<=1)printf("%d\n",black-1);
else printf("%d\n",A.top());
}
}
return 0;
}