cppAcademy
FROM LEARNING TO COMPETING

Proficient.
Put your skills to the test.

Bulgarian Informatics Group B · 2009–2026

217 independently explained problems: 54 Municipal, 54 Regional and 109 National. Start with the easier tasks and work upwards. Difficulty labels are learning estimates, not official ratings; Group B also includes challenging national-level problems. National-round tasks shared by Groups A and B are included. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP B2023 · EasyTree traversal

Company Hierarchy

National Olympiad — Municipal round (2023 season)

Submission name: subord.cpp

Problem summary

Given a rooted employee hierarchy, answer how many strict descendants each queried employee has. Employee numbers need not follow the hierarchy.

Input

N, N−1 directed boss/subordinate pairs U V, Q, then Q employee numbers.

Output

For each query, print the number of direct and indirect subordinates.

Constraints

1 ≤ N ≤ 100000; 1 ≤ U,V,M ≤ N; 1 ≤ Q ≤ N; the relations form a rooted tree.

Worked example

An independently prepared example for this explanation.

Input

4
1 3
2 1
2 4
3
1
2
4

Output

1
3
0

Solution analysis

  1. Record the parent and children of each employee. The root is the unique employee without a parent; it need not be employee 1.
  2. Build an iterative traversal order with each parent before its children. Process that order backwards, adding each child’s subtree size to its parent. Initialize every subtree size to one for the employee itself.
  3. In the sample, employee 2 is the root, with children 1 and 4; employee 1 has child 3. Subtree sizes are 4 for employee 2, 2 for employee 1, and 1 for leaves 3 and 4. Subtract one to get answers 3,1,0.

Why it works

In reverse traversal order all children are processed before their parent. Their disjoint subtrees, together with the parent itself, form exactly the parent’s subtree, so summing their sizes is correct by induction. Strict descendants exclude the queried employee, giving subtreeSize−1.

Complexity: O(N+Q) time and O(N) space.

Watch out. Do not assume the root is 1. Exclude the employee from their own subordinate count. Iterative traversal avoids recursion depth failure on a chain.

Commented C++17 solution

An independently written complete program with standard headers.

#include<iostream>
#include<vector>
// Algorithm: Record the parent and children of each employee.
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin>>n;
    vector<vector<int>>children(n+1);
    vector<int>parent(n+1,0),size(n+1,1);
    for(int i=1;i<n;++i){
        int boss,employee;
        cin>>boss>>employee;
        parent[employee]=boss;
        children[boss].push_back(employee);
    }
    int root=1;
    while(parent[root]!=0){
        root=parent[root];
    }
    vector<int>order(1,root);
    for(int i=0;i<static_cast<int>(order.size());++i){
        for(int child:children[order[i]]){
            order.push_back(child);
        }
    }
    for(int i=n-1;i>0;--i){
        int employee=order[i];
        size[parent[employee]]+=size[employee];
    }
    int queries;
    cin>>queries;
    while(queries--){
        int employee;
        cin>>employee;
        cout<<size[employee]-1<<'\n';
    }
}

Source: Arena Olimpiici ↗