【DFS序+树状数组】HDU 3887 Counting Offspring

http://acm.hdu.edu.cn/showproblem.php?pid=3887

【题意】

  • 给定一棵树,给定这棵树的根
  • 对于每个结点,统计子树中编号比他小的结点个数
  • 编号从小到大一次输出

【思路】

  • 从小到大处理每个结点,即统计当前结点的结果后,把当前结点插入到树状数组中

【AC】

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 
 5 const int maxn=1e5+2;
 6 const int maxm=2*maxn; 
 7 int n,rt;
 8 struct edge
 9 {
10     int to;
11     int nxt;
12 }e[maxm];
13 int head[maxn];
14 int tot;
15 int cid;
16 int l[maxn],r[maxn]; 
17 int tree[maxm];
18 int lowbit(int x)
19 {
20     return x&(-x);
21 }
22 void add(int k,int x)
23 {
24     while(k<=cid)
25     {
26         tree[k]+=x;
27         k+=lowbit(k);
28     }
29 }
30 int query(int k)
31 {
32     int ans=0;
33     while(k)
34     {
35         ans+=tree[k];
36         k-=lowbit(k);
37     }
38     return ans;
39 }
40 void init()
41 {
42     memset(head,-1,sizeof(head));
43     tot=0;
44     cid=0;
45     memset(tree,0,sizeof(tree));
46 }
47 
48 void addedge(int u,int v)
49 {
50     e[tot].to=v;
51     e[tot].nxt=head[u];
52     head[u]=tot++;
53 }
54 void dfs(int u,int pa)
55 {
56     l[u]=++cid;
57     for(int i=head[u];i!=-1;i=e[i].nxt)
58     {
59         int v=e[i].to;
60         if(v==pa) continue;
61         dfs(v,u); 
62     }
63     r[u]=++cid;
64 } 
65 
66 
67 int main()
68 {
69     while(~scanf("%d%d",&n,&rt))
70     {
71         if(n+rt==0) break;
72         init();
73         int u,v;
74         for(int i=1;i<=n-1;i++)
75         {
76             scanf("%d%d",&u,&v);
77             addedge(u,v);
78             addedge(v,u);
79         }
80         dfs(rt,-1);
81         for(int i=1;i<=n;i++)
82         {
83             int ans=query(r[i])-query(l[i]-1);
84             if(i==1) printf("%d",ans);
85             else printf(" %d",ans);
86             add(l[i],1);
87         }
88         puts("");
89     }
90     return 0;
91 } 
树状数组

 

posted @ 2017-08-23 20:59  shulin15  阅读(187)  评论(0编辑  收藏  举报