bzoj 1103
先处理出整棵树的DFS序,用树状数组维护 DFS序的差分序列的前缀和。
初始在每个城市的入点处+1,出点处-1,如果有土路被改造成公路,
就把它通向城市的入点处-1,出点处+1。
/**/ #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int mxn=600000; int in[mxn],out[mxn],cnt=0; int n,m; //邻接表 struct edge { int v,nxt; } e[mxn]; int hd[mxn],mct=0; void add_edge(int u,int v) { e[++mct].v=v; e[mct].nxt=hd[u]; hd[u]=mct; return; } //树状数组 int t[mxn]; inline int lowbit(int x) { return x&-x; } void add(int p,int v) { while(p<=cnt) { t[p]+=v; p+=lowbit(p); } } int smm(int x) { int res=0; while(x) { res+=t[x]; x-=lowbit(x); } return res; } //DFS序 void DFS(int u,int fa) { in[u]=++cnt; for(int i=hd[u]; i; i=e[i].nxt) { int v=e[i].v; if(v==fa)continue; DFS(v,u); } out[u]=++cnt; } int main() { scanf("%d",&n); int i,j; int u,v; for(i=1; i<n; i++) { scanf("%d%d",&u,&v); add_edge(u,v); add_edge(v,u); } DFS(1,0); for(i=2; i<=n; i++) { add(in[i],1); add(out[i],-1); } scanf("%d",&m); char ch[5]; for(i=1; i<=m+n-1; i++) { scanf("%s",ch); if(ch[0]=='A') { scanf("%d%d",&u,&v); add(in[v],-1); add(out[v],1); } else { scanf("%d",&u); printf("%d\n",smm(in[u])); } } return 0; }