传送门:http://poj.org/problem?id=3321
题意:
给定一棵树,动态询问节点的和;
题解:dfs建立一棵树,保证父节点大于子节点,且其所有子节点连续,这样就可以用树状数组来做了,ps:写完总是TLE,从网上查了查改成typedef vector<int> INT,vector<INT>
真的就过了,难道typedef有优化效果??vector<vector<int>>似乎比vector<list<int>>快…………
/*
ID:iamzky
OJ:POJ
Index:3321
Language:C++
*/
#include<map>
#include<list>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define iter list<int>::iterator
using namespace std;
typedef vector<int > INT;
vector<INT >Son;
int d[100001];
int s[100001];
int t[100001];
int M[100001];
int a[100001];
int vis[100001];
int n,m;
int tot=0;
//int in[100001];
inline int lowbit(int x){return x&(-x);}
void dfs(int x){
s[x]=++tot;
for(int i=0;i<Son[x].size();i++){
int u=Son[x][i];
if(!vis[u]){
vis[u]=1;
dfs(u);
}
}
t[x]=tot;
}
int get(int x){
int s=0;
while(x){
s+=d[x];
x-=lowbit(x);
}
return s;
}
void change(int x){
int x0=x;
if(!a[x])
while(x<=n){
d[x]++;
x+=lowbit(x);
}
else
while(x<=n){
d[x]--;
x+=lowbit(x);
}
a[x0]=1-a[x0];
}
int main(){
int u,v,x;
scanf("%d",&n);
Son.resize(n+1);
memset(d,0,sizeof(d));
memset(a,0,sizeof(a));
//memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
change(i);
}
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
Son[u].push_back(v);
Son[v].push_back(u);
}
vis[1]=1;
dfs(1);
char ch[10];
scanf("%d\n",&m);
for(int i=1;i<=m;i++){
scanf("%s",ch);
scanf("%d",&x);
if(ch[0]=='Q'){
printf("%d\n",get(t[x])-get(s[x]-1));
}
if(ch[0]=='C'){
change(s[x]);
}
}
return 0;
}