在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了。
不过,她经常回忆起以前在乡间漫步的情景。昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双
向的土路。从每个村庄都恰好有一条路径到达村庄1(即比特堡)。并且,对于每个村庄,它到比特堡的路径恰好
只经过编号比它的编号小的村庄。另外,对于所有道路而言,它们都不在除村庄以外的其他地点相遇。在这个未开
化的地方,从来没有过高架桥和地下铁道。随着时间的推移,越来越多的土路被改造成了公路。至今,Blue Mary
还清晰地记得最后一条土路被改造为公路的情景。现在,这里已经没有土路了——所有的路都成为了公路,而昔日
的村庄已经变成了一个大都市。 Blue Mary想起了在改造期间她送信的经历。她从比特堡出发,需要去某个村庄,
并且在两次送信经历的间隔期间,有某些土路被改造成了公路.现在Blue Mary需要你的帮助:计算出每次送信她需
要走过的土路数目。(对于公路,她可以骑摩托车;而对于土路,她就只好推车了。)
第一行是一个数n(1 < = n < = 2 50000).以下n-1行,每行两个整数a,b(1 < = a以下一行包含一个整数m
(1 < = m < = 2 50000),表示Blue Mary曾经在改造期间送过m次信。以下n+m-1行,每行有两种格式的若干信息
,表示按时间先后发生过的n+m-1次事件:若这行为 A a b(a若这行为 W a, 则表示Blue Mary曾经从比特堡送信到
村庄a。
有m行,每行包含一个整数,表示对应的某次送信时经过的土路数目。
1 //It is made by jump~
2 #include <iostream>
3 #include <cstdlib>
4 #include <cstring>
5 #include <cstdio>
6 #include <cmath>
7 #include <algorithm>
8 using namespace std;
9 typedef long long LL;
10 const int MAXN = 250011;
11 const int inf = (1<<30);
12 int n,total,ecnt,ans;
13 int id[MAXN],ql,qr;
14 int pre[MAXN],TT;
15 int top[MAXN],siz[MAXN],zhongerzi[MAXN],father[MAXN],deep[MAXN];
16 int next[MAXN*2],to[MAXN*2],first[MAXN];
17 char ch[12];
18
19 struct node{
20 int sum;
21 }a[MAXN*4];
22 inline void link(int x,int y){ next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; }
23 inline int getint()
24 {
25 int w=0,q=0;
26 char c=getchar();
27 while((c<‘0‘ || c>‘9‘) && c!=‘-‘) c=getchar();
28 if (c==‘-‘) q=1, c=getchar();
29 while (c>=‘0‘ && c<=‘9‘) w=w*10+c-‘0‘, c=getchar();
30 return q ? -w : w;
31 }
32
33 inline void build(int root,int l,int r){
34 if(l==r){ if(l!=1) a[root].sum=1; else a[root].sum=0; return ; }
35 int lc=root*2,rc=lc+1;
36 int mid=(l+r)/2; build(lc,l,mid); build(rc,mid+1,r);
37 a[root].sum=a[lc].sum+a[rc].sum;
38 }
39
40 inline void dfs1(int u,int fa){
41 siz[u]=1;
42 for(int i=first[u];i;i=next[i]){
43 int v=to[i]; if(v==fa) continue;
44 father[v]=u;deep[v]=deep[u]+1;
45 dfs1(v,u);siz[u]+=siz[v];
46 if(siz[v]>siz[ zhongerzi[u] ]) zhongerzi[u]=v;
47 }
48 }
49
50 inline void dfs2(int u,int fa){
51 id[u]=++total; pre[total]=u;
52 if(zhongerzi[u]) { top[zhongerzi[u]]=top[u];dfs2(zhongerzi[u],u); }
53 for(int i=first[u];i;i=next[i]){
54 int v=to[i]; if(v==fa || v==zhongerzi[u]) continue;
55 top[v]=v; dfs2(v,u);
56 }
57 }
58
59 inline void querysum(int root,int l,int r){
60 if(ql<=l && r<=qr) { ans+=a[root].sum; return ; }
61 int mid=(l+r)/2; int lc=root*2,rc=lc+1;
62 if(ql<=mid) querysum(lc,l,mid);
63 if(qr>mid) querysum(rc,mid+1,r);
64 }
65
66 inline int findsum(int x){
67 int f1=top[x]; ans=0;
68 while(f1!=0){
69 ql=id[f1]; qr=id[x]; querysum(1,1,n);
70 x=father[f1]; f1=top[x];
71 }
72 return ans;
73 }
74
75 inline void update(int root,int l,int r){
76 if(l==r) { a[root].sum=0; return ; }
77 int mid=(l+r)/2; int lc=root*2,rc=lc+1;
78 if(TT<=mid) update(lc,l,mid); else update(rc,mid+1,r);
79 a[root].sum=a[lc].sum+a[rc].sum;
80 }
81
82 inline void work(){
83 n=getint(); int x,y;
84 for(int i=1;i<n;i++){
85 x=getint();y=getint(); if(x>y) swap(x,y);
86 link(x,y);
87 }
88 deep[1]=1; dfs1(1,0);
89 top[1]=1; dfs2(1,0);
90 build(1,1,n);
91 int Q=getint(); Q+=n-1;
92
93 for(int i=1;i<=Q;i++){
94 scanf("%s",ch);
95 if(ch[0]==‘W‘){
96 x=getint();
97 printf("%d\n",findsum(x));
98 }
99 else{
100 x=getint(); y=getint(); if(x<y) swap(x,y); TT=id[x];
101 update(1,1,n);
102 }
103 }
104 }
105
106 int main()
107 {
108 work();
109 return 0;
110 }