留坑,以后一定会回来调的
#include<algorithm>
#include<assert.h>
#include<ctype.h>
#include<cstdio>
#define INF 2147483647
#define N 200020
using namespace std;
inline int read(){
int x=0,f=1;char c;
do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c));
do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c));
return x*f;
}
int n,m,x,y,id,top,T;
int fir[N],dfn[N],siz[N],f[N][21],dep[N],pret[N];
char s[105];
struct Edge{
int to,nex;
Edge(){}
Edge(int to,int nex):to(to),nex(nex){}
}nex[N<<1];
struct SNode{
SNode *ls,*rs;
int sum,v;
SNode():ls(NULL),rs(NULL),sum(0),v(0){}
inline void maintain(){
sum=ls->sum+rs->sum;
}
inline void pushdown(int L,int R){
if(v){
int mid=(L+R)>>1;
ls->v+=v;rs->v+=v;
ls->sum+=(mid-L+1)*v;rs->sum+=(R-(mid+1)+1)*v;
v=0;
}
}
}*root;
struct Node{
Node *fa,*ch[2];
int id,l,r;bool rev;
Node(int);
inline int dir(){
if(fa->ch[0]==this) return 0;
if(fa->ch[1]==this) return 1;
return -1;
}
inline void maintain(){
l=min(dfn[id],min(ch[0]->l,ch[1]->l));
r=max(dfn[id],max(ch[0]->r,ch[1]->r));
}
inline void pushdown();
}*pre[N],*null;
Node::Node(int x):id(x){
fa=ch[0]=ch[1]=null;
rev=false;
}
inline void Node::pushdown(){
if(rev){
if(ch[0]!=null){
ch[0]->rev^=1;
swap(ch[0]->ch[0],ch[0]->ch[1]);
}
if(ch[1]!=null){
ch[1]->rev^=1;
swap(ch[1]->ch[0],ch[1]->ch[1]);
}
rev=0;
}
}
inline void init(){
null=new Node(0);
null->ch[0]=null->ch[1]=null->fa=null;
null->r=-1;null->l=INF;
pre[0]=null;
}
inline void add(int x,int y){
nex[++top]=Edge(y,fir[x]);
fir[x]=top;
}
void dfs(int x,int fa){
dfn[x]=++T;siz[x]=1;pret[T]=x;
f[x][0]=fa;dep[x]=dep[fa]+1;
pre[x]=new Node(x);
pre[x]->fa=pre[fa];
pre[x]->l=pre[x]->r=dfn[x];
for(int i=fir[x];i;i=nex[i].nex){
if(nex[i].to==fa) continue;
dfs(nex[i].to,x);
siz[x]+=siz[nex[i].to];
}
}
void build(int L,int R,SNode *&k){
k=new SNode();
if(L==R) return void(k->sum=dep[pret[L]]);
int mid=(L+R)>>1;
build(L,mid,k->ls);build(mid+1,R,k->rs);
k->maintain();
}
void Add(int L,int R,int x,int y,int v,SNode *k){
if(L>=x && R<=y){
k->sum+=(R-L+1)*v;
k->v+=v;
return;
}
int mid=(L+R)>>1;
k->pushdown(L,R);
if(y<=mid) Add(L,mid,x,y,v,k->ls);
else if(x>mid) Add(mid+1,R,x,y,v,k->rs);
else Add(L,mid,x,y,v,k->ls),Add(mid+1,R,x,y,v,k->rs);
k->maintain();
}
inline int Query(int L,int R,int x,int y,SNode *k){
if(L>=x && R<=y) return k->sum;
int mid=(L+R)>>1;
k->pushdown(L,R);
if(y<=mid) return Query(L,mid,x,y,k->ls);
else if(x>mid) return Query(mid+1,R,x,y,k->rs);
else return Query(L,mid,x,y,k->ls)+Query(mid+1,R,x,y,k->rs);
}
inline int LCA(int x,int y){
if(dep[x]<dep[y]) return LCA(y,x);
for(int i=20;~i;i--)
if(dep[f[x][i]]>=dep[y])
x=f[x][i];
if(x==y) return x;
for(int i=20;~i;i--)
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
inline void Add_Tree(int x,int v){
if(x>0 && x<=n){
//printf("%d %d\n",x,v);
int t=x;
if(t==id) Add(1,n,1,n,v,root);
else{
int y=LCA(t,id);
if(t==y){
y=id;
for(int j=20;~j;j--)
if(dep[f[y][j]]>dep[x])
y=f[y][j];
//printf("ooooo%d\n",y);
Add(1,n,1,n,v,root);Add(1,n,dfn[y],dfn[y]+siz[y]-1,-v,root);
}
else Add(1,n,dfn[t],dfn[t]+siz[t]-1,v,root);
}
}
}
inline void Rotate(Node *x,int d){
Node *k=x->ch[d^1];
int tmp;
x->ch[d^1]=k->ch[d];
if(x->ch[d^1]!=null) x->ch[d^1]->fa=x;
k->ch[d]=x;
if(~(tmp=x->dir())) x->fa->ch[tmp]=k;
k->fa=x->fa;x->fa=k;
x->maintain();k->maintain();
}
inline void To_Pushdown(Node *x){
if(~x->dir()) To_Pushdown(x->fa);
x->pushdown();
return;
}
inline void Splay(Node *x){
assert(x!=null);
To_Pushdown(x);
int tmp;
while(~(tmp=x->dir())){
while(x->fa->dir()==tmp)
Rotate(x->fa->fa,tmp^1);
Rotate(x->fa,tmp^1);
}
return;
}
inline void Access(Node *x){
Node *pre=null;
while(x!=null){
//printf("pp%d\n",x->id);
Splay(x);
Add_Tree(pre->id,-1);
Add_Tree(x->ch[1]->id,1);
x->ch[1]=pre;pre=x;
x=x->fa;
}
return;
}
inline void Make_root(Node *x){
Access(x);Splay(x);
x->rev^=1;swap(x->ch[0],x->ch[1]);
return;
}
inline void init_LCA(){
for(int j=1;j<=20;j++)
for(int i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1];
return;
}
int main(){
n=read();m=read();
for(int i=1;i<n;i++){
x=read();y=read();
add(x,y);add(y,x);
}
id=1;
init();
dfs(1,0);build(1,n,root);
init_LCA();
for(int i=1;i<=m;i++){
scanf("%s",s+1);x=read();
if(s[3]=='L') Access(pre[x]);
else if(s[3]=='C'){
Make_root(pre[x]);id=x;
}
else{
if(x==id) printf("%.10lf\n",1.0*Query(1,n,1,n,root)/(1.0*n));
else{
y=LCA(x,id);
if(x==y){
y=id;
for(int j=20;~j;j--)
if(dep[f[y][j]]>dep[x])
y=f[y][j];
printf("%.10lf\n",1.0*(Query(1,n,1,n,root)-Query(1,n,dfn[y],dfn[y]+siz[y]-1,root))/(1.0*(n-siz[y])));
}
else printf("%.10lf\n",1.0*Query(1,n,dfn[x],dfn[x]+siz[x]-1,root)/(1.0*siz[x]));
}
}
}
return 0;
}