Counting Offspring(hdu3887)

来源:互联网 发布:算法导论 pdf 99 编辑:程序博客网 时间:2024/06/01 09:58

 

Counting Offspring

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2759    Accepted Submission(s): 956


Problem Description
You are given a tree, it’s root is p, and the node is numbered from 1 to n. Now define f(i) as the number of nodes whose number is less than i in all the succeeding nodes of node i. Now we need to calculate f(i) for any possible i.
 

 

Input
Multiple cases (no more than 10), for each case:
The first line contains two integers n (0<n<=10^5) and p, representing this tree has n nodes, its root is p.
Following n-1 lines, each line has two integers, representing an edge in this tree.
The input terminates with two zeros.
 

 

Output
For each test case, output n integer in one line representing f(1), f(2) … f(n), separated by a space.
 

 

Sample Input
15 7
7 10
7 1
7 9
7 3
7 4
10 14
14 2
14 13
9 11
9 6
6 5
6 8
3 15
3 12
0 0
思路:dfs序+线段树;
首先dfs序线性化,然后我们知道,如果某点是另个点的孩子节点,那么他必然在被另一个点的父亲节点所包括,所以从小到大查询[l[i],r[i]]区间的和,往线段树加点单点更新。复杂度n*log(n);
 1 #include<stdio.h> 2 #include<algorithm> 3 #include<queue> 4 #include<stdlib.h> 5 #include<iostream> 6 #include<string.h> 7 #include<set> 8 #include<map> 9 #include<vector>10 using namespace std;11 typedef long long LL;12 typedef vector<int>Ve;13 vector<Ve>vec(100005);14 bool flag[100005];15 int l[100005];16 int r[100005];17 int id[100005];18 int cn = 0;19 void dfs(int n);20 21 int tree[100005*4];22 void up(int l,int r,int k,int nn,int mm);23 int ask(int l,int r,int k,int nn,int mm);24 int main(void)25 {26     int n,p;27     while(scanf("%d %d",&n,&p),n!=0&&p!=0)28     {   cn = 0;29         for(int i = 0;i < 100005;i++)30             vec[i].clear();31         memset(flag,0,sizeof(flag));32         for(int i = 0;i < n-1;i++)33         {34             int x,y;35             scanf("%d %d",&x,&y);36             vec[x].push_back(y);37             vec[y].push_back(x);38         }39         dfs(p);40         memset(tree,0,sizeof(tree));41         for(int i = 1;i <= n;i++)42         {43             if(i == 1)44                 printf("%d",ask(l[i],r[i],0,1,cn));45                 else printf(" %d",ask(l[i],r[i],0,1,cn));46             up(l[i],l[i],0,1,cn);47         }48         printf("\n");49     }50     return 0;51 }52 void dfs(int n)53 {54     flag[n] = true;55     l[n] = ++cn;56     for(int i = 0;i < vec[n].size();i++)57     {58         int d = vec[n][i];59         if(!flag[d])60             dfs(d);61     }r[n] = cn;62 }63 void up(int l,int r,int k,int nn,int mm)64 {65     if(l > mm||r < nn)66     {67         return ;68     }69     else if(l <= nn&&r >= mm)70     {71         tree[k]++;return ;72     }73     up(l,r,2*k+1,nn,(nn+mm)/2);74     up(l,r,2*k+2,(nn+mm)/2+1,mm);75     tree[k] = tree[2*k+1]+tree[2*k+2];76 }77 int ask(int l,int r,int k,int nn,int mm)78 {79     if(l > mm||r < nn)80     {81         return 0;82     }83     else if(l <= nn&&r >= mm)84     {85         return tree[k];86     }87     else88     {89         int nx = ask(l,r,2*k+1,nn,(nn+mm)/2);90         int ny = ask(l,r,2*k+2,(nn+mm)/2+1,mm);91         return nx + ny;92     }93 }

 

 

 

Sample Output
0 0 0 0 0 1 6 0 3 1 0 0 0 2 0
 
0 0
原创粉丝点击