POJ3321

题目大意:1e5个点的树,节点值为1。1e5次操作,将节点的值异或1,或者求点x为根的子树的节点权值和。(树的根为1号点)

简单的DFS序问题

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 const int  maxn=1e5+10;
 6 int n,m;
 7 struct edge
 8 {
 9     int u,v,nxt;
10 }e[maxn<<1];
11 int head[maxn],js;
12 void addage(int u,int v)
13 {
14     e[++js].u=u;e[js].v=v;
15     e[js].nxt=head[u];head[u]=js;
16 }
17 int lt[maxn],rt[maxn],cnt,sz[maxn];
18 bool ap[maxn];
19 void dfs(int u,int fa)
20 {
21     lt[u]=++cnt;
22     for(int i=head[u];i;i=e[i].nxt)
23     {
24         int v=e[i].v;
25         if(v==fa)continue;
26         dfs(v,u);
27     }
28     rt[u]=cnt;
29 }
30 void change(int x,int y)
31 {
32     for(int i=x;i<=n;i+=i&(-i))sz[i]+=y;
33 }
34 int query(int x)
35 {
36     int ans=0;
37     for(int i=x;i>0;i-=i&(-i))ans+=sz[i];
38     return ans;
39 }
40 int main()
41 {
42     scanf("%d",&n);
43     for(int u,v,i=1;i<n;++i)
44     {
45         scanf("%d%d",&u,&v);
46         addage(u,v);addage(v,u);
47     }
48     dfs(1,0);
49     scanf("%d",&m);
50     char s[3];
51     int x;
52     while(m--)
53     {
54         scanf("%s%d",s,&x);
55         if(s[0]=='Q')printf("%d\n",rt[x]-lt[x]+1-query(rt[x])+query(lt[x]-1));
56         else 
57         {
58             if(ap[x]==0)
59             {
60                 ap[x]=1;
61                 change(lt[x],1);
62             }
63             else
64             {
65                 ap[x]=0;
66                 change(lt[x],-1);
67             }
68         }
69     }
70     return 0;
71 }
View Code

 

posted on 2019-11-04 17:09  gryzy  阅读(197)  评论(0编辑  收藏  举报

导航