# Count of distinct colors in a subtree of a Colored Tree with given min frequency for Q queries

Given a N-ary tree with some colour associated with every node and **Q** queries. Each query contains two integers **A** and **X**. The task is to count all distinct colors in a subtree rooted at **A**, having frequency of colors greater than or equal to **X** in that subtree.

**Examples:**

Input:Tree:1(1) / \ / \ 2(2) 5(3) / \ / | \ / \ / | \ 3(2) 4(3) 6(2) 7(3) 8(3)query[] = {{1, 2}, {1, 3}, {1, 4}, {2, 3}, {5, 3}}

Output:{2, 2, 1, 0, 1}

Explanation:

In the subtree rooted at 1, the frequency of colour 2 is 3 and colour 3 is 4. So the answer is 2 for the 1 query, 2 for 2nd query and 1 for 3rd query.

For subtree rooted at 2, frequency of color 2 is 2 and color 3 is 1. So no color have frequency more than or equal to 4.

For subtree rooted at 5, frequency of color 2 is 1 and color 3 is 3. So color 3 have frequency equal to 3.

** Naive Approach **

- For each query, we’ll traverse the whole subtree of the given node.
- We’ll maintain a map which stores the frequency of every colour in the subtree of given node.
- Then, traverse the map and count number of colours such that it’s frequency is greater than given x.

**Time Complexity:** O(Q * N)

**Space Complexity:** O(Q * N)

** Approach: (Using Mo’s Algorithm) **

- We’ll first flat the tree using Euler Tour.
- We’ll give the number to every node, when it will go in the DFS and when it came out. Let’s denote this with
**tin[node]**and**tout[node]**for every node. - After we have flatten the tree into an array, every sub tree of can be denoted as some some array with start and end index as
**tin[node]**and**tout[node]**respectively. - Now the question changed into number of elements with frequency greater than equal to
**X**in some subarray. - We’ll use Mo’s algorithm to solve this problem.
- First, we’ll store the queries and sort them according to the
**tin[node] / SQ**where**SQ**is the Square root of**N**. - As we move the pointers, we’ll store the frequency at ith colour in an array and answer to the query is stored at
**X**th position of array as it stores the count of colours with frequnecy greater equal to X.

`// C++ program to count distinct colors ` `// in a subtree of a Colored Tree ` `// with given min frequency for Q queries ` ` ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `const` `int` `N = 1e5 + 5; ` ` ` `// graph as adjacency list ` `vector<vector<` `int` `> > v(N); ` ` ` `// colour written on node. ` `vector<` `int` `> colour(N); ` ` ` `// order of node entering in DFS ` `vector<` `int` `> in(N); ` ` ` `// order of node exiting in DFS ` `vector<` `int` `> out(N); ` ` ` `// for counting the frequency of ` `// nodes with colour i ` `vector<` `int` `> cnt(N); ` ` ` `// for storing frequency of colours ` `vector<` `int` `> freq(N); ` ` ` `// tree in a flatten ` `// form (using Euler tour) ` `vector<` `int` `> flatTree(N); ` ` ` `// number of nodes ` `int` `n, ` ` ` ` ` `// square root of n ` ` ` `sq; ` ` ` `// indexes for in and ` `// out of node in DFS ` `int` `start = 0; ` ` ` `// DFS function to find ` `// order of euler tour ` `void` `DFSEuler(` `int` `a, ` `int` `par) ` `{ ` ` ` ` ` `// stroing the start index ` ` ` `in[a] = ++start; ` ` ` ` ` `// storing colour of node ` ` ` `// in flatten array ` ` ` `flatTree[start] = colour[a]; ` ` ` ` ` `for` `(` `int` `i : v[a]) { ` ` ` ` ` `// doing DFS on its child ` ` ` `// skipping parent ` ` ` `if` `(i == par) ` ` ` `continue` `; ` ` ` ` ` `DFSEuler(i, a); ` ` ` `} ` ` ` ` ` `// out index of the node. ` ` ` `out[a] = start; ` `} ` ` ` `// comparator for queries ` `bool` `comparator(pair<` `int` `, ` `int` `>& a, ` ` ` `pair<` `int` `, ` `int` `>& b) ` `{ ` ` ` `// comparator for queries to be ` ` ` `// sorted accoring to in[x] / sq ` ` ` `if` `(in[a.first] / sq != in[b.first] / sq) ` ` ` `return` `in[a.first] < in[b.first]; ` ` ` ` ` `return` `out[a.first] < out[b.first]; ` `} ` ` ` `// Function to answer the queries ` `void` `solve(vector<pair<` `int` `, ` `int` `> > arr, ` ` ` `int` `q) ` `{ ` ` ` `sq = ` `sqrt` `(n) + 1; ` ` ` ` ` `// for storing answers ` ` ` `vector<` `int` `> answer(q); ` ` ` ` ` `// for storing indexes of queries ` ` ` `// in the order of input. ` ` ` `map<pair<` `int` `, ` `int` `>, ` `int` `> idx; ` ` ` ` ` `for` `(` `int` `i = 0; i < q; i++) { ` ` ` ` ` `// storing indexes of queries ` ` ` `idx[arr[i]] = i; ` ` ` `} ` ` ` ` ` `// doing depth first search to ` ` ` `// find indexes to flat the ` ` ` `// tree using euler tour. ` ` ` `DFSEuler(1, 0); ` ` ` ` ` `// After doing Euler tour, ` ` ` `// subtree of x can be ` ` ` `// represented as a subarray ` ` ` `// from in[x] to out[x]; ` ` ` ` ` `// we'll sort the queries ` ` ` `// according to the in[i]; ` ` ` `sort(arr.begin(), ` ` ` `arr.end(), ` ` ` `comparator); ` ` ` ` ` `// two pointers for ` ` ` `// sliding the window ` ` ` `int` `l = 1, r = 0; ` ` ` ` ` `for` `(` `int` `i = 0; i < q; i++) { ` ` ` ` ` `// finding answer to the query ` ` ` `int` `node = arr[i].first, ` ` ` `x = arr[i].second; ` ` ` `int` `id = idx[arr[i]]; ` ` ` ` ` `while` `(l > in[node]) { ` ` ` ` ` `// decrementing the pointer as ` ` ` `// it is greater than start ` ` ` `// and adding answer ` ` ` `// to our freq array. ` ` ` `l--; ` ` ` `cnt[flatTree[l]]++; ` ` ` `freq[cnt[flatTree[l]]]++; ` ` ` `} ` ` ` ` ` `while` `(r < out[node]) { ` ` ` ` ` `// incrementing pointer as it is ` ` ` `// less than the end value and ` ` ` `// adding answer to our freq array. ` ` ` `r++; ` ` ` `cnt[flatTree[r]]++; ` ` ` `freq[cnt[flatTree[r]]]++; ` ` ` `} ` ` ` ` ` `while` `(l < in[node]) { ` ` ` ` ` `// removing the lth node from ` ` ` `// freq array and incrementing ` ` ` `// the pointer ` ` ` `freq[cnt[flatTree[l]]]--; ` ` ` `cnt[flatTree[l]]--; ` ` ` `l++; ` ` ` `} ` ` ` ` ` `while` `(r > out[node]) { ` ` ` ` ` `// removing the rth node from ` ` ` `// freq array and decrementing ` ` ` `// the pointer ` ` ` `freq[cnt[flatTree[r]]]--; ` ` ` `cnt[flatTree[r]]--; ` ` ` `r--; ` ` ` `} ` ` ` ` ` `// answer to this query ` ` ` `// is stored at freq[x] ` ` ` `// freq[x] stores the frequency ` ` ` `// of nodes greater equal to x ` ` ` `answer[id] = freq[x]; ` ` ` `} ` ` ` ` ` `// printing the queries ` ` ` `for` `(` `int` `i = 0; i < q; i++) ` ` ` `cout << answer[i] << ` `" "` `; ` `} ` ` ` `int` `main() ` `{ ` ` ` `// Driver Code ` ` ` `/* ` ` ` `1(1) ` ` ` `/ \ ` ` ` `/ \ ` ` ` `2(2) 5(3) ` ` ` `/ \ / | \ ` ` ` `/ \ / | \ ` ` ` `3(2) 4(3) 6(2) 7(3) 8(3) ` ` ` `*/` ` ` `n = 8; ` ` ` `v[1].push_back(2); ` ` ` `v[2].push_back(1); ` ` ` `v[2].push_back(3); ` ` ` `v[3].push_back(2); ` ` ` `v[2].push_back(4); ` ` ` `v[4].push_back(2); ` ` ` `v[1].push_back(5); ` ` ` `v[5].push_back(1); ` ` ` `v[5].push_back(6); ` ` ` `v[6].push_back(5); ` ` ` `v[5].push_back(7); ` ` ` `v[7].push_back(5); ` ` ` `v[5].push_back(8); ` ` ` `v[8].push_back(5); ` ` ` ` ` `colour[1] = 1; ` ` ` `colour[2] = 2; ` ` ` `colour[3] = 2; ` ` ` `colour[4] = 3; ` ` ` `colour[5] = 3; ` ` ` `colour[6] = 2; ` ` ` `colour[7] = 3; ` ` ` `colour[8] = 3; ` ` ` ` ` `vector<pair<` `int` `, ` `int` `> > queries ` ` ` `= { { 1, 2 }, ` ` ` `{ 1, 3 }, ` ` ` `{ 1, 4 }, ` ` ` `{ 2, 3 }, ` ` ` `{ 5, 3 } }; ` ` ` `int` `q = queries.size(); ` ` ` ` ` `solve(queries, q); ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

2 2 1 0 1

**Time Complexity: **

**Space Complexity: **

## Recommended Posts:

- Querying the number of distinct colors in a subtree of a colored tree using BIT
- Count of distinct numbers in an Array in a range for Online Queries using Merge Sort Tree
- Queries for DFS of a subtree in a tree
- Find GCD of each subtree of a given node in an N-ary Tree for Q queries
- Count of nodes having odd divisors in the given subtree for Q queries
- Number of ways to paint a tree of N nodes with K distinct colors with given conditions
- Count of subtrees from an N-ary tree consisting of single colored nodes
- Count of distinct characters in a substring by given range for Q queries
- Color tree with minimum colors such that colors of edges incident to a vertex are different
- String Range Queries to count number of distinct characters with updates
- Queries for M-th node in the DFS of subtree
- Count of paths in given Binary Tree with odd bitwise AND for Q queries
- Queries for the number of nodes having values less than V in the subtree of a Node
- Queries for the count of even digit sum elements in the given range using Segment Tree.
- Number of strictly increasing Buildings from right with distinct Colors
- Find the minimum spanning tree with alternating colored edges
- Even size subtree in n-ary tree
- Subtree with given sum in a Binary Tree
- Subtree of all nodes in a tree using DFS
- Check if a binary tree is subtree of another binary tree using preorder traversal : Iterative

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.