题目大意:
修改树上的节点,然后求子树的和。
思路分析:
dfs 重新编号,烂大街了。。。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define maxn 100005
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
using namespace std;
int num[maxn];
int ed[maxn];
int tot[maxn<<2];
void pushup(int num)
{
tot[num]=tot[num<<1]+tot[num<<1|1];
}
void build(int num,int s,int e)
{
if(s==e)
{
tot[num]=1;
return;
}
int mid=(s+e)>>1;
build(lson);
build(rson);
pushup(num);
}
void update(int num,int s,int e,int pos)
{
if(s==e)
{
tot[num]^=1;
return;
}
int mid=(s+e)>>1;
if(pos<=mid)update(lson,pos);
else update(rson,pos);
pushup(num);
}
int query(int num,int s,int e,int l,int r)
{
if(l<=s && r>=e){
return tot[num];
}
int mid=(s+e)>>1;
if(r<=mid)return query(lson,l,r);
else if(l>mid)return query(rson,l,r);
else return query(lson,l,mid)+query(rson,mid+1,r);
}
int id;
int next[maxn<<1];
int head[maxn];
int to[maxn<<1];
void addedge(int u,int v)
{
id++;
next[id]=head[u];
to[id]=v;
head[u]=id;
}
int cnt=1;
bool vis[maxn];
int dfs(int cur)
{
num[cur]=cnt++;
ed[num[cur]]=num[cur];
for(int p=head[cur]; p ;p=next[p])
{
if(vis[to[p]])continue;
vis[to[p]]=true;
ed[num[cur]] = max(ed[num[cur]],dfs(to[p]));
}
return ed[num[cur]];
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(vis,false,sizeof vis);
memset(head,0,sizeof head);
memset(ed,0,sizeof ed);
id=0,cnt=1;
for(int i=1;i<=n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
vis[1]=true;
dfs(1);
int m;
scanf("%d",&m);
char str[2];
build(1,1,cnt-1);
while(m--)
{
int op;
scanf("%s%d",str,&op);
if(str[0]=='Q')
{
printf("%d\n",query(1,1,cnt-1,num[op],ed[num[op]]));
}
else update(1,1,cnt-1,num[op]);
}
}
return 0;
}
/*
4
1 2
1 3
2 4
2 5
*/