预处理出每个点到根节点的土路数,插到一个树状数组里,然后每次修改只会对子树中的节点造成影响,于是相当于区间修改、点查询了。
#include<cstdio> using namespace std; #define N 250001 int n,en,v[N<<1],next[N<<1],first[N],m; void AddEdge(const int &U,const int &V) { v[++en]=V; next[en]=first[U]; first[U]=en; } int now,Ls[N],Rs[N],fa[N],a[N]; void dfs(int U) { Ls[U]=++now; for(int i=first[U];i;i=next[i]) if(v[i]!=fa[U]) { fa[v[i]]=U; a[v[i]]=a[U]+1; dfs(v[i]); } Rs[U]=now; } int d[N]; void add_node(int p,const int &v){for(;p<=n;p+=(p&(-p)))d[p]+=v;} void add_range(const int &L,const int &R,const int &v){add_node(L,v);if(R!=n)add_node(R+1,-v);} int query(int p){int res=0;for(;p;p-=(p&(-p)))res+=d[p];return res;} int main() { int A,B; char op[2]; scanf("%d",&n); for(int i=1;i<n;++i) { scanf("%d%d",&A,&B); AddEdge(A,B); AddEdge(B,A); } dfs(1); for(int i=2;i<=n;++i) add_range(Ls[i],Ls[i],a[i]); scanf("%d",&m); for(int i=1;i<n+m;++i) { scanf("%s%d",op,&A); if(op[0]=='W') printf("%d ",query(Ls[A])); else { scanf("%d",&B); if(fa[A]==B) add_range(Ls[A],Rs[A],-1); else add_range(Ls[B],Rs[B],-1); } } return 0; }