题目背景
作为一位ikun,小T决定在生日这一天为坤坤做些什么。

她决定向全村的人民宣传坤坤。她所在的村庄是一个\(n\)个节点的树。并且这棵树以1号点为根。每个节点上有一位村民,他们初始每个人对坤坤可能喜欢(用1表示),也可能讨厌(用0表示)。

接下来她会进行m次操作,第i次操作形如:

"S x" 表示向点x的子树内的每个人安利一次坤坤。这会让本来喜欢坤坤的人变得讨厌坤坤,而本来讨厌坤坤的人变得喜欢

"Q x" 表示询问点x的子树内有多少人喜欢坤坤??????

你能帮帮她么?

输入格式
第一行两个正整数\(n,m\),分别表示树的点数和操作个数。

接下来一行一个长度为\(n\)的01串,第\(i\)位描述编号为\(i\)的村民的初始状态。1表示喜欢,0表示不喜欢。

接下来\(n?1\)行每行两个数\(x_i,y_i\),表示一条边。

接下来\(m\)行,每行描述一个操作,具体格式如题面所述。

输出格式
对于每个询问,输出一行表示答案。

样例1
input

5 5
11100
1 2
2 3
2 4
3 5
Q 5
Q 4
S 4
Q 1
S 4

output

0
0
4

样例2
input

5 5
01111
1 2
1 3
3 4
1 5
S 5
Q 3
S 5
Q 1
S 1

output

2
4

限制与规定
对于\(30\%\)的数据,\(n,q\le10^3\)

对于\(50\%\)的数据,保证数据随机。

另有\(20\%\)的数据,保证树的形态是一条链。

对于\(100\%\)的数据,\(n,q\le10^5,1≤x_i,y_i\),每个操作中的\(x\le n\)

时间限制:1s
空间限制:512MB

区间取反和求和,都是线段树能做的事。所以考虑能不能把树转化成线段,然后再用线段树执行操作。
很明显,如果想要这样做的花,需要把每棵子树放在一起,那么dfs序刚好符合要求。
按照dfs序维护线段树即可。

#include
const int N=1e5+5;
int n,m,idx,x,y,in[N],hd[N],tag[N<<2],tr[N<<2],sz[N],a[N];
char c;
struct edge{
	int v,nxt;
}e[N<<1];
void add_edge(int x,int y,int z)
{
	e[z]=(edge){y,hd[x]};
	hd[x]=z;
}
void pushdown(int o,int l,int r)
{
	int mid=(l+r)>>1;
	tr[o<<1]=(mid-l+1)-tr[o<<1];
	tr[o<<1|1]=(r-mid)-tr[o<<1|1];
	tag[o<<1]^=1,tag[o<<1|1]^=1;
	tag[o]=0;
}
void update(int o,int l,int r,int x,int y)
{
	if(x<=l&&r<=y)
	{
		tr[o]=(r-l+1)-tr[o];
		tag[o]^=1;
		return;
	}
	int mid=l+r>>1;
	if(tag[o])
		pushdown(o,l,r);
	if(mid>=x)
		update(o<<1,l,mid,x,y);
	if(mid>1,ret=0;
	if(tag[o])
		pushdown(o,l,r);
	if(mid>=x)
		ret+=query(o<<1,l,mid,x,y);
	if(mid