12.3闲话
前言
我的zz主题会让一些东西变得很小,谁能给我个正常点的主题谢谢
正文
推歌,校长异托邦新曲
简介
「不老不死」讲的是人对命运的哀叹,
「我约等于世界」就是关于人对命运的反抗。
我命由我不由天,
从来就没有什么救世主,
我们的路,需要自己来闯。
女孩从迷茫中觉醒,
成为真正的自己。
她意识到这个世界再也不是与她无关,而是紧密相连。
她需要用自己的力量去改变世界,
她约等于世界。
作词·作曲·编曲·调校:阿良良木健
曲绘:LUNE
【自我版】视频制作:NEKOLOCO(敬请期待)
我约等于世界
我将那世界抵抗 用我的模样
不自量力的妄想 镌刻在心脏
神明不能支配我 用挂碍阻挡
我是我 不熄灭 的光芒
我将那世界抵抗 呐喊在激荡
用血肉立下愿望 要推倒围墙
我孤身矗立蛮荒 面对着刀枪
不后悔 不后退 不认输 不投降
就算沉睡了千年 万物被埋葬
和平的梦仍只是 唯美的空想
撕裂的大地只剩 百孔与千疮
爱变成 不存在 的巨谎
我不再念想 谁会挺身 来救世的愿望
上帝 与众神 已死亡
难道我们 不该循从 自由形状?
我的命运 就要 我自己构想
我存在 就是我的一切
我掌握着命数 无惧无常的劫
我存在 不会有人改写
我是我的上帝 我不轻易妥协
Woo woo 我不属于异类
Woo woo 我约等于世界
将愤恨化作鸣掌 夜空里回响
让眼泪融进武装 去撕开真相
永生是我的丧殇 也是我力量
用我命 佑天地 盼我族 永盛昌
我只为我 自己而活 余者皆是对象
不顺从 他人的眼光
总有质疑 声音飘扬 笑我痴狂
他不曾 看到我 血液仍未凉
我存在 就是我的一切
我掌握着命数 无惧无常的劫
我存在 不会有人改写
我是我的上帝 我不轻易妥协
我存在 就是我的一切
我掌握着命数 无惧无常的劫
我存在 不会有人改写
我是我的上帝 我不轻易妥协
Woo woo 故事尚未终结
Woo woo 我在等待明天
Woo woo 我不属于异类
Woo woo 我约等于世界
今天练树剖换根
Description
给定一棵大小为 n 的有根点权树,支持以下操作:
• 换根
• 修改点权
• 查询子树最小值Input
第一行两个整数 n, Q ,分别表示树的大小和操作数。
接下来n行,每行两个整数f,v,第i+1行的两个数表示点i的父亲和点i的权。保证f < i。如 果f = 0,那么i为根。输入数据保证只有i = 1时,f = 0。
接下来 m 行,为以下格式中的一种:
• V x y表示把点x的权改为y
• E x 表示把有根树的根改为点 x
• Q x 表示查询点 x 的子树最小值Output
对于每个 Q ,输出子树最小值。
换根板子题,但是还是疯狂WA
第0次 -> 段错误,核心已转储 0pts
忘保存了
读入格式错了
第1次 -> MLE 0pts
#include<bits/stdc++.h>
#define MAXM 0X66CCFF
#define int long long
#define INF 0X66CCFF0712
namespace IO{
inline void close(){std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);}
inline void Fire(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
inline int read(){int s = 0,w = 1;char ch = getchar();while(ch<'0'||ch>'9'){ if(ch == '-') w = -1;ch = getchar();}while(ch>='0'&&ch<='9'){ s = s*10+ch-'0';ch = getchar();}return s*w;}
inline void write(int x){char F[200];int tmp=x>0?x:-x,cnt=0;;if(x<0)putchar('-') ;while(tmp>0){F[cnt++]=tmp%10+'0';tmp/=10;}while(cnt>0)putchar(F[--cnt]);}
}
using namespace IO;
int head[MAXM],NEXT[MAXM],TO[MAXM],cnt,tot,a[MAXM],R,root,N,M;
struct node{
int fa,dep,siz,son,top;
int dfn,rnk;
}T[MAXM];
namespace Grape{
inline void add(int u,int v){
NEXT[++tot]=head[u];
TO[tot]=v;
head[u]=tot;
}
}
namespace ST{
#define mid (l+r)/2
#define lC q<<1
#define rC q<<1|1
struct St{
long long l,r,siz;
long long lazy,dat,mindat;
}t[0x66ccff];
void build(int q,int l,int r){
t[q].l=l;
t[q].r=r;
t[q].siz=r-l+1;
t[lC].mindat=INF;
t[rC].mindat=INF;
if(l==r){
t[q].mindat=a[T[l].rnk];
return;
}
build(lC,l,mid);
build(rC,mid+1,r);
t[q].mindat=std::min(t[lC].mindat,t[rC].mindat);
}
void change(int q,int l,int r,int v){
if(t[q].l>r||t[q].r<l) return;
if(t[q].l>=l && t[q].r<=r){
t[q].dat=v;
return;
}
change(lC,l,r,v);
change(rC,l,r,v);
t[q].mindat=std::min(t[lC].mindat,t[rC].mindat);
}
inline int Askmin(int q,int l,int r){
if(t[q].l>r || t[q].r<l)
return INF;
if(t[q].l>=l && t[q].r<=r)
return t[q].mindat;
return std::min(Askmin(lC,l,r),Askmin(rC,l,r));
}
}
namespace killTree{
inline void Dfs1(int q){
T[q].son=-1;
T[q].siz=1;
for(int j=head[q];j;j=NEXT[j]){
if(T[TO[j]].dep) continue;
T[TO[j]].dep=T[q].dep+1;
T[TO[j]].fa=q;
Dfs1(TO[j]);
T[q].siz+=T[TO[j]].siz;
if((T[q].son==-1) || (T[TO[j]].siz>T[T[q].son].siz)) T[q].son=TO[j];
}
}
inline void Dfs2(int q,int v){
T[q].top=v;
T[q].dfn=++cnt;
T[cnt].rnk=q;
if(T[q].son==-1)
return;
Dfs2(T[q].son,v);
for(int j=head[q];j;j=NEXT[j]){
if((TO[j]!=T[q].fa)&&(TO[j]!=T[q].son))
Dfs2(TO[j],TO[j]);
}
}
inline int Get(int x,int y){
while(T[x].top!=T[y].top){
if(T[T[x].top].dep < T[T[y].top].dep) std::swap(x,y);
if(T[T[x].top].fa == y) return T[x].top;
x=T[T[x].top].fa;
}
if(T[x].dep>T[y].dep) std::swap(x,y);
return T[x].son;
}
inline void TreeAdd(int x,int y,int val){
while(T[x].top!=T[y].top){
if(T[T[x].top].dep<T[T[y].top].dep)
std::swap(x,y);
ST::change(1,T[T[x].top].dfn,T[x].dfn,val);
x=T[T[x].top].fa;
}
if(T[x].dep>T[y].dep)
std::swap(x,y);
ST::change(1,T[x].dfn,T[y].dfn,val);
}
inline int AskTree(int x){
if(x == root) return ST::t[1].mindat;
else if(T[x].dfn>T[root].dfn || T[x].dfn+T[x].siz-1<T[root].dfn)
return ST::Askmin(1,T[x].dfn,T[x].dfn+T[x].siz-1);
else{
int ch=Get(x,root);
if(T[ch].dfn+T[ch].siz-1==N)
return ST::Askmin(1,1,T[ch].dfn-1);
else return std::min(ST::Askmin(1,1,T[ch].dfn-1),ST::Askmin(1,T[ch].dfn+T[ch].siz,N));
}
}
inline void EXchange(int x){
root=x;
}
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
N=read(),M=read();
for(int i=1;i<=N;i++)
a[i]=read();
read();read();
for(int i=2;i<=N;i++){
int u=read(),v=read();
Grape::add(u,v);
Grape::add(v,u);
}
T[1].dep=1;
killTree::Dfs1(1);
killTree::Dfs2(1,1);
ST::build(1,1,N);
for(register int i=1;i<=M;i++){
char q=getchar();
if(q=='V'){
int x=read(),y=read();
killTree::TreeAdd(x,x,y);
}
else if(q=='E'){
int x=read();
killTree::EXchange(x);
}
else if(q=='Q'){
int x=read();
std::cout<<killTree::AskTree(x)<<std::endl;
}
}
}
原因:问题出在root没初始化成1
第2次 -> WA 9pts
#include<bits/stdc++.h>
#define MAXM 0X66CCFF
#define int long long
#define INF 0X66CCFF0712
namespace IO{
inline void close(){std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);}
inline void Fire(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
inline int read(){int s = 0,w = 1;char ch = getchar();while(ch<'0'||ch>'9'){ if(ch == '-') w = -1;ch = getchar();}while(ch>='0'&&ch<='9'){ s = s*10+ch-'0';ch = getchar();}return s*w;}
inline void write(int x){char F[200];int tmp=x>0?x:-x,cnt=0;;if(x<0)putchar('-') ;while(tmp>0){F[cnt++]=tmp%10+'0';tmp/=10;}while(cnt>0)putchar(F[--cnt]);}
}
using namespace IO;
int head[MAXM],NEXT[MAXM],TO[MAXM],cnt,tot,a[MAXM],R,root=1,N,M;
struct node{
int fa,dep,siz,son,top;
int dfn,rnk;
}T[MAXM];
namespace Grape{
inline void add(int u,int v){
NEXT[++tot]=head[u];
TO[tot]=v;
head[u]=tot;
}
}
namespace ST{
#define mid (l+r)/2
#define lC q<<1
#define rC q<<1|1
struct St{
long long l,r,siz;
long long lazy,dat,mindat;
}t[0x66ccff];
void build(int q,int l,int r){
t[q].l=l;
t[q].r=r;
t[q].siz=r-l+1;
t[lC].mindat=INF;
t[rC].mindat=INF;
if(l==r){
t[q].mindat=a[T[l].rnk];
return;
}
build(lC,l,mid);
build(rC,mid+1,r);
t[q].mindat=std::min(t[lC].mindat,t[rC].mindat);
}
void change(int q,int l,int r,int v){
if(t[q].l>r||t[q].r<l) return;
if(t[q].l>=l && t[q].r<=r){
t[q].dat=v;
return;
}
change(lC,l,r,v);
change(rC,l,r,v);
t[q].mindat=std::min(t[lC].mindat,t[rC].mindat);
}
inline int Askmin(int q,int l,int r){
if(t[q].l>r || t[q].r<l)
return INF;
if(t[q].l>=l && t[q].r<=r)
return t[q].mindat;
return std::min(Askmin(lC,l,r),Askmin(rC,l,r));
}
}
namespace killTree{
inline void Dfs1(int q){
T[q].son=-1;
T[q].siz=1;
for(int j=head[q];j;j=NEXT[j]){
if(T[TO[j]].dep) continue;
T[TO[j]].dep=T[q].dep+1;
T[TO[j]].fa=q;
Dfs1(TO[j]);
T[q].siz+=T[TO[j]].siz;
if((T[q].son==-1) || (T[TO[j]].siz>T[T[q].son].siz)) T[q].son=TO[j];
}
}
inline void Dfs2(int q,int v){
T[q].top=v;
T[q].dfn=++cnt;
T[cnt].rnk=q;
if(T[q].son==-1)
return;
Dfs2(T[q].son,v);
for(int j=head[q];j;j=NEXT[j]){
if((TO[j]!=T[q].fa)&&(TO[j]!=T[q].son))
Dfs2(TO[j],TO[j]);
}
}
inline int Get(int x,int y){
while(T[x].top!=T[y].top){
if(T[T[x].top].dep < T[T[y].top].dep) std::swap(x,y);
if(T[T[x].top].fa == y) return T[x].top;
x=T[T[x].top].fa;
}
if(T[x].dep>T[y].dep) std::swap(x,y);
return T[x].son;
}
inline void TreeAdd(int x,int y,int val){
while(T[x].top!=T[y].top){
if(T[T[x].top].dep<T[T[y].top].dep)
std::swap(x,y);
ST::change(1,T[T[x].top].dfn,T[x].dfn,val);
x=T[T[x].top].fa;
}
if(T[x].dep>T[y].dep)
std::swap(x,y);
ST::change(1,T[x].dfn,T[y].dfn,val);
}
inline int AskTree(int x){
if(x == root) {
#ifdef debug
return 0X66CCFF;
#endif
return ST::t[1].mindat;
}
else if(T[x].dfn>T[root].dfn || T[x].dfn+T[x].siz-1<T[root].dfn){
#ifdef debug
return 0X66CCFF;//marked
#endif
return ST::Askmin(1,T[x].dfn,T[x].dfn+T[x].siz-1);
}
else{
int ch=Get(x,root);
if(T[ch].dfn+T[ch].siz-1==N)
return ST::Askmin(1,1,T[ch].dfn-1);
else return std::min(ST::Askmin(1,1,T[ch].dfn-1),ST::Askmin(1,T[ch].dfn+T[ch].siz,N));
}
}
inline void EXchange(int x){
root=x;
}
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
N=read(),M=read();
read();
a[1]=read();
for(int i=2;i<=N;i++){
int u=read();
a[i]=read();
Grape::add(u,i);
Grape::add(i,u);
}
T[1].dep=1;
killTree::Dfs1(1);
killTree::Dfs2(1,1);
ST::build(1,1,N);
for(register int i=1;i<=M;i++){
char q=getchar();
if(q=='V'){
int x=read();
killTree::TreeAdd(x,x,read());
}
else if(q=='E'){
killTree::EXchange(read());
}
else if(q=='Q'){
std::cout<<killTree::AskTree(read())<<std::endl;
}
}
}
原因:(当时以为) 这题给的是点权,要先转成边权😓😓😓
第3次 -> 没评测 ?pts
忘存代码了
原因:😓😓😓转成了边权然后发现其实转不转都一样又删了
第4次- > AC 100pts
#include<bits/stdc++.h>
#define MAXM 0X66CCFF
#define int long long
#define INF 0X66CCFF0712
namespace IO{
inline void close(){std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);}
inline void Fire(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
inline int read(){int s = 0,w = 1;char ch = getchar();while(ch<'0'||ch>'9'){ if(ch == '-') w = -1;ch = getchar();}while(ch>='0'&&ch<='9'){ s = s*10+ch-'0';ch = getchar();}return s*w;}
inline void write(int x){char F[200];int tmp=x>0?x:-x,cnt=0;;if(x<0)putchar('-') ;while(tmp>0){F[cnt++]=tmp%10+'0';tmp/=10;}while(cnt>0)putchar(F[--cnt]);}
}
using namespace IO;
int head[MAXM],NEXT[MAXM],TO[MAXM],cnt,tot,a[MAXM],R,root=1,N,M;
struct node{
int fa,dep,siz,son,top;
int dfn,rnk;
}T[MAXM];
namespace Grape{
inline void add(int u,int v){
NEXT[++tot]=head[u];
TO[tot]=v;
head[u]=tot;
}
}
namespace ST{
#define mid (l+r)/2
#define lC q<<1
#define rC q<<1|1
struct St{
long long l,r,siz;
long long lazy,dat,mindat;
}t[0x66ccff];
void build(int q,int l,int r){
t[q].l=l;
t[q].r=r;
t[q].siz=r-l+1;
t[lC].mindat=INF;
t[rC].mindat=INF;
if(l==r){
t[q].mindat=a[T[l].rnk];
return;
}
build(lC,l,mid);
build(rC,mid+1,r);
t[q].mindat=std::min(t[lC].mindat,t[rC].mindat);
}
void change(int q,int l,int r,int v){
if(t[q].l>r||t[q].r<l) return;
if(t[q].l>=l && t[q].r<=r){
t[q].mindat=v;
return;
}
change(lC,l,r,v);
change(rC,l,r,v);
t[q].mindat=std::min(t[lC].mindat,t[rC].mindat);
}
inline int Askmin(int q,int l,int r){
if(t[q].l>r || t[q].r<l)
return INF;
if(t[q].l>=l && t[q].r<=r)
return t[q].mindat;
return std::min(Askmin(lC,l,r),Askmin(rC,l,r));
}
}
namespace killTree{
inline void Dfs1(int q){
T[q].son=-1;
T[q].siz=1;
for(int j=head[q];j;j=NEXT[j]){
if(T[TO[j]].dep) continue;
T[TO[j]].dep=T[q].dep+1;
T[TO[j]].fa=q;
Dfs1(TO[j]);
T[q].siz+=T[TO[j]].siz;
if((T[q].son==-1) || (T[TO[j]].siz>T[T[q].son].siz)) T[q].son=TO[j];
}
}
inline void Dfs2(int q,int v){
T[q].top=v;
T[q].dfn=++cnt;
T[cnt].rnk=q;
if(T[q].son==-1)
return;
Dfs2(T[q].son,v);
for(int j=head[q];j;j=NEXT[j]){
if((TO[j]!=T[q].fa)&&(TO[j]!=T[q].son))
Dfs2(TO[j],TO[j]);
}
}
inline int lca(int u,int v){
while(T[u].top!=T[v].top) {
if(T[T[u].top].dep > T[T[v].top].dep) u=T[T[u].top].fa;
else v=T[T[v].top].fa;
}
return T[u].dep>T[v].dep?v:u;
}
inline int Get(int x,int y){
while(T[x].top!=T[y].top){
if(T[T[x].top].dep < T[T[y].top].dep) std::swap(x,y);
if(T[T[x].top].fa == y) return T[x].top;
x=T[T[x].top].fa;
}
if(T[x].dep>T[y].dep) std::swap(x,y);
return T[x].son;
}
inline void TreeAdd(int x,int y,int val){
while(T[x].top!=T[y].top){
if(T[T[x].top].dep<T[T[y].top].dep)
std::swap(x,y);
ST::change(1,T[T[x].top].dfn,T[x].dfn,val);
x=T[T[x].top].fa;
}
if(T[x].dep>T[y].dep)
std::swap(x,y);
ST::change(1,T[x].dfn,T[y].dfn,val);
}
inline int AskTree(int x){
if(x==root){
#ifdef debug
return 0X66CCFF;
#endif
return ST::t[1].mindat;
}
else if(T[x].dfn>T[root].dfn || T[x].dfn+T[x].siz-1<T[root].dfn){
#ifdef debug
return 0X66CCFF;//marked
#endif
return ST::Askmin(1,T[x].dfn,T[x].dfn+T[x].siz-1);
}
else{
int ch=Get(x,root);
if(T[ch].dfn+T[ch].siz-1==N)
return ST::Askmin(1,1,T[ch].dfn-1);
else return std::min(ST::Askmin(1,1,T[ch].dfn-1),ST::Askmin(1,T[ch].dfn+T[ch].siz,N));
}
}
inline void EXchange(int x){
root=x;
}
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
N=read(),M=read();
read();
a[1]=read();
for(int i=2;i<=N;i++){
int u=read();
a[i]=read();
Grape::add(u,i);
Grape::add(i,u);
}
T[1].dep=1;
killTree::Dfs1(1);
killTree::Dfs2(1,1);
ST::build(1,1,N);
for(register int i=1;i<=M;i++){
char q=getchar();
if(q=='V'){
int x=read();
killTree::TreeAdd(x,x,read());
}
else if(q=='E'){
killTree::EXchange(read());
}
else if(q=='Q'){
std::cout<<killTree::AskTree(read())<<std::endl;
}
}
}
这个属实没绷住
我打的是
t[q].dat=v;
然后在debug的时候发现诶我怎么没修改啊
哦应该是t[q].mindat=v;
数据范围太大把我树剖卡掉了
可能是我菜
-
update
果然是我菜,我调出来了
#include<bits/stdc++.h>
#define MAXM 0X66CCFF
#define int long long
namespace IO{
inline void close(){std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);}
inline void Fire(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
inline int read(){int s = 0,w = 1;char ch = getchar();while(ch<'0'||ch>'9'){ if(ch == '-') w = -1;ch = getchar();}while(ch>='0'&&ch<='9'){ s = s*10+ch-'0';ch = getchar();}return s*w;}
inline void write(int x){char F[200];int tmp=x>0?x:-x,cnt=0;;if(x<0)putchar('-') ;while(tmp>0){F[cnt++]=tmp%10+'0';tmp/=10;}while(cnt>0)putchar(F[--cnt]);}
}
using namespace IO;
int head[MAXM],NEXT[MAXM],TO[MAXM],cnt,tot,a[MAXM],R;
struct node{
int fa,dep,siz,son,top;
int dfn,rnk;
}T[MAXM];
namespace Grape{
inline void add(int u,int v){
NEXT[++tot]=head[u];
TO[tot]=v;
head[u]=tot;
}
}
namespace ST{
#define mid (l+r)/2
#define lC q<<1
#define rC q<<1|1
struct St{
long long l,r,siz;
long long lazy,dat;
}t[0x66ccff];
void build(int q,int l,int r){
t[q].l=l;
t[q].r=r;
t[q].siz=r-l+1;
if(l==r){
t[q].dat=1;
return;
}
build(lC,l,mid);
build(rC,mid+1,r);
t[q].dat=t[lC].dat+t[rC].dat;
}
void lazy(int q){
t[lC].lazy+=t[q].lazy;
t[lC].dat+=(t[lC].siz)*t[q].lazy;
t[rC].lazy+=t[q].lazy;
t[rC].dat+=(t[rC].siz)*t[q].lazy;
t[q].lazy=0;
}
void change(int q,int l,int r,int v){
if(t[q].l>r||t[q].r<l) return;
if(t[q].l>=l && t[q].r<=r){
t[q].dat=v;
return;
}
change(lC,l,r,v);
change(rC,l,r,v);
t[q].dat=t[lC].dat+t[rC].dat;
}
long long asksum(int q,int l,int r){
if(t[q].l>r || t[q].r<l)
return 0;
if(t[q].l>=l && t[q].r<=r)
return t[q].dat;
return asksum(lC,l,r)+asksum(rC,l,r);
}
}
namespace killTree{
inline void Dfs1(int q){
T[q].son=-1;
T[q].siz=1;
for(int j=head[q];j;j=NEXT[j]){
if(T[TO[j]].dep) continue;
T[TO[j]].dep=T[q].dep+1;
T[TO[j]].fa=q;
Dfs1(TO[j]);
T[q].siz+=T[TO[j]].siz;
if((T[q].son==-1) || (T[TO[j]].siz>T[T[q].son].siz)) T[q].son=TO[j];
}
}
inline void Dfs2(int q,int v){
T[q].top=v;
T[q].dfn=++cnt;
T[cnt].rnk=q;
if(T[q].son==-1)
return;
Dfs2(T[q].son,v);
for(int j=head[q];j;j=NEXT[j]){
if((TO[j]!=T[q].fa)&&(TO[j]!=T[q].son))
Dfs2(TO[j],TO[j]);
}
}
inline void TreeAdd(int x,int y,int val){
while(T[x].top!=T[y].top){
if(T[T[x].top].dep<T[T[y].top].dep)
std::swap(x,y);
ST::change(1,T[T[x].top].dfn,T[x].dfn,val);
x=T[T[x].top].fa;
}
if(T[x].dep>T[y].dep)
std::swap(x,y);
ST::change(1,T[x].dfn,T[y].dfn,val);
}
inline int TreeSum(int x,int y){
int ans=0;
while(T[x].top!=T[y].top){
if(T[T[x].top].dep<T[T[y].top].dep) std::swap(x,y);
ans=ans+ST::asksum(1,T[T[x].top].dfn,T[x].dfn);
x=T[T[x].top].fa;
}
if(T[x].dep>T[y].dep) std::swap(x,y);
return ans+ST::asksum(1,T[x].dfn,T[y].dfn);
}
inline void AddTree(int x,int val){
ST::change(1,T[x].dfn,T[x].dfn+T[x].siz-1,val);
}
inline int AskTree(int x){
return ST::asksum(1,T[x].dfn,T[x].dfn+T[x].siz-1);
}
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
int N=read(),M;R=1;
for(int i=1;i<N;i++){
int u=read(),v=read();
Grape::add(u,v);
Grape::add(v,u);
}
T[R].dep=1;
killTree::Dfs1(R);
killTree::Dfs2(R,R);
ST::build(1,1,N);
M=read();
for(int i=1;i<=N+M-1;i++){
char q=getchar();
if(q=='A'){
int x=read(),y=read();
if(T[x].dep<T[y].dep) std::swap(x,y);
killTree::TreeAdd(x,x,0);
}
else if(q=='W'){
int x=read();
std::cout<<killTree::TreeSum(1,x)-1<<std::endl;
}
}
}