Related Articles

# Queries to calculate Bitwise OR of each subtree of a given node in an N-ary Tree

• Last Updated : 22 Jun, 2021

Given an N-ary Tree consisting of N nodes valued from 1 to N, an array arr[] consisting of N positive integers, where arr[i] is the value associated with the ith node, and Q queries, each consisting of a node. The task for each query is to find the Bitwise OR of node values present in the subtree of the given node.

Examples:

Input: arr[] = {2, 3, 4, 8, 16} Queries[]: {2, 3, 1} Output: 3 28 31
Explanation:
Query 1: Bitwise OR(subtree(Node 2)) = Bitwise OR(Node 2) = Bitwise OR(3) = 3
Query 2: Bitwise OR(subtree(Node 3)) = Bitwise OR(Node 3, Node 4, Node 5) = Bitwise OR(4, 8, 16) = 28
Query 3: Bitwise OR(subtree(Node 1)) = Bitwise OR(Node1, Node 2, Node 3, Node 4, Node 5) = Bitwise OR(2, 3, 4, 8, 16) = 31

Input: arr[] = {2, 3, 4, 8, 16} Queries[]: {4, 5} Output: 8 16
Explanation:
Query 1: Bitwise OR(subtree(Node 4)) = bitwise OR(Node 4) = 8
Query 2: Bitwise OR(subtree(Node 5)) = bitwise OR(Node 5) = 16

Naive Approach: The simplest approach to solve this problem is to traverse the subtree of the given node and for each query, calculate the Bitwise OR of every node in the subtree of that node and print that value.
Time Complexity: O(Q * N)
Auxiliary Space: O(Q * N)

Efficient Approach: To optimize the above approach, the idea is to precompute the Bitwise OR of all subtrees present in the given tree, and for each query, find the Bitwise XOR of subtrees for every given node. Follow the steps below to solve the problem:

• Initialize a vector ans[] to store the Bitwise OR of all subtrees present in the given Tree.
• Precompute the Bitwise OR for every subtree using Depth First Search(DFS).
• If the node is a leaf node, the bitwise OR of this node is the node value itself.
• Otherwise, the Bitwise OR for the subtree is equal to the Bitwise OR of all subtree values of its children.
• After completing the above steps, print the value stored at ans[Queries[i]] for every ith query.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `// Maximum Number of nodes``const` `int` `N = 1e5 + 5;` `// Adjacency list``vector<``int``> adj[N];` `// Stores Bitwise OR of each node``vector<``int``> answer(N);` `// Function to add edges to the Tree``void` `addEdgesToGraph(``int` `Edges[],``                     ``int` `N)``{``    ``// Traverse the edges``    ``for` `(``int` `i = 0; i < N - 1; i++) {``        ``int` `u = Edges[i];``        ``int` `v = Edges[i];` `        ``// Add edges``        ``adj[u].push_back(v);``        ``adj[v].push_back(u);``    ``}``}` `// Function to perform DFS``// Traversal on the given tree``void` `DFS(``int` `node, ``int` `parent, ``int` `Val[])``{``    ``// Initialize answer with bitwise``    ``// OR of current node``    ``answer[node] = Val[node];` `    ``// Iterate over each child``    ``// of the current node``    ``for` `(``int` `child : adj[node]) {` `        ``// Skip parent node``        ``if` `(child == parent)``            ``continue``;` `        ``// Call DFS for each child``        ``DFS(child, node, Val);` `        ``// Taking bitwise OR of the``        ``// answer of the child to``        ``// find node's OR value``        ``answer[node] = (answer[node]``                        ``| answer[child]);``    ``}``}` `// Function to call DFS from the'=``// root for precomputing answers``void` `preprocess(``int` `Val[])``{``    ``DFS(1, -1, Val);``}` `// Function to calculate and print``// the Bitwise OR for Q queries``void` `findSubtreeOR(``int` `Queries[], ``int` `Q,``                   ``int` `Val[])``{``    ``// Perform preprocessing``    ``preprocess(Val);` `    ``// Iterate over each given query``    ``for` `(``int` `i = 0; i < Q; i++) {` `        ``cout << answer[Queries[i]]``             ``<< ``' '``;``    ``}``}` `// Utility function to find and``// print bitwise OR for Q queries``void` `findSubtreeORUtil(``    ``int` `N, ``int` `Edges[], ``int` `Val[],``    ``int` `Queries[], ``int` `Q)``{``    ``// Function to add edges to graph``    ``addEdgesToGraph(Edges, N);` `    ``// Function call``    ``findSubtreeOR(Queries, Q, Val);``}` `// Driver Code``int` `main()``{``    ``// Number of nodes``    ``int` `N = 5;``    ``int` `Edges[]``        ``= { { 1, 2 }, { 1, 3 },``            ``{ 3, 4 }, { 3, 5 } };` `    ``int` `Val[] = { 0, 2, 3, 4, 8, 16 };``    ``int` `Queries[] = { 2, 3, 1 };` `    ``int` `Q = ``sizeof``(Queries)``            ``/ ``sizeof``(Queries);` `    ``// Function call``    ``findSubtreeORUtil(N, Edges, Val,``                      ``Queries, Q);` `    ``return` `0;``}`

## Java

 `// Java program for above approach``import` `java.util.*;``import` `java.lang.*;``import` `java.io.*;` `class` `GFG``{` `  ``// Maximum Number of nodes``  ``static` `int` `N = (``int``)1e5 + ``5``;` `  ``// Adjacency list``  ``static` `ArrayList> adj;` `  ``// Stores Bitwise OR of each node``  ``static` `int``[] answer;` `  ``// Function to add edges to the Tree``  ``static` `void` `addEdgesToGraph(``int` `Edges[][],``                              ``int` `N)``  ``{``    ``// Traverse the edges``    ``for` `(``int` `i = ``0``; i < N - ``1``; i++)``    ``{``      ``int` `u = Edges[i][``0``];``      ``int` `v = Edges[i][``1``];` `      ``// Add edges``      ``adj.get(u).add(v);``      ``adj.get(v).add(u);``    ``}``  ``}` `  ``// Function to perform DFS``  ``// Traversal on the given tree``  ``static` `void` `DFS(``int` `node, ``int` `parent, ``int` `Val[])``  ``{` `    ``// Initialize answer with bitwise``    ``// OR of current node``    ``answer[node] = Val[node];` `    ``// Iterate over each child``    ``// of the current node``    ``for` `(Integer child : adj.get(node))``    ``{` `      ``// Skip parent node``      ``if` `(child == parent)``        ``continue``;` `      ``// Call DFS for each child``      ``DFS(child, node, Val);` `      ``// Taking bitwise OR of the``      ``// answer of the child to``      ``// find node's OR value``      ``answer[node] = (answer[node]``                      ``| answer[child]);``    ``}``  ``}` `  ``// Function to call DFS from the'=``  ``// root for precomputing answers``  ``static` `void` `preprocess(``int` `Val[])``  ``{``    ``DFS(``1``, -``1``, Val);``  ``}` `  ``// Function to calculate and print``  ``// the Bitwise OR for Q queries``  ``static` `void` `findSubtreeOR(``int` `Queries[], ``int` `Q,``                            ``int` `Val[])``  ``{``    ` `    ``// Perform preprocessing``    ``preprocess(Val);` `    ``// Iterate over each given query``    ``for` `(``int` `i = ``0``; i < Q; i++)``    ``{``      ``System.out.println(answer[Queries[i]] + ``" "``);``    ``}``  ``}` `  ``// Utility function to find and``  ``// print bitwise OR for Q queries``  ``static` `void` `findSubtreeORUtil(``int` `N, ``int` `Edges[][],``                                ``int` `Val[], ``int` `Queries[],``                                ``int` `Q)``  ``{` `    ``// Function to add edges to graph``    ``addEdgesToGraph(Edges, N);` `    ``// Function call``    ``findSubtreeOR(Queries, Q, Val);``  ``}` `  ``// Driver function``  ``public` `static` `void` `main (String[] args)``  ``{` `    ``adj = ``new` `ArrayList<>();``    ``for``(``int` `i = ``0``; i < N; i++)``      ``adj.add(``new` `ArrayList<>());``    ``answer = ``new` `int``[N];``    ``N = ``5``;``    ``int` `Edges[][] = { { ``1``, ``2` `}, { ``1``, ``3` `},``                     ``{ ``3``, ``4` `}, { ``3``, ``5` `} };` `    ``int` `Val[] = { ``0``, ``2``, ``3``, ``4``, ``8``, ``16` `};``    ``int` `Queries[] = { ``2``, ``3``, ``1` `};``    ``int` `Q = Queries.length;` `    ``// Function call``    ``findSubtreeORUtil(N, Edges, Val,``                      ``Queries, Q);``  ``}``}` `// This code is contributed by offbeat`

## Python3

 `# Python3 program for the above approach`` ` `# Maximum Number of nodes``N ``=` `100005``;`` ` `# Adjacency list``adj ``=` `[[] ``for` `i ``in` `range``(N)];`` ` `# Stores Bitwise OR of each node``answer ``=` `[``0` `for` `i ``in` `range``(N)]`` ` `# Function to add edges to the Tree``def` `addEdgesToGraph(Edges, N):` `    ``# Traverse the edges``    ``for` `i ``in` `range``(N ``-` `1``):``    ` `        ``u ``=` `Edges[i][``0``];``        ``v ``=` `Edges[i][``1``];`` ` `        ``# Add edges``        ``adj[u].append(v);``        ``adj[v].append(u);``    ` `# Function to perform DFS``# Traversal on the given tree``def` `DFS(node, parent, Val):` `    ``# Initialize answer with bitwise``    ``# OR of current node``    ``answer[node] ``=` `Val[node];`` ` `    ``# Iterate over each child``    ``# of the current node``    ``for` `child ``in` `adj[node]:``    ` `        ``# Skip parent node``        ``if` `(child ``=``=` `parent):``            ``continue``;`` ` `        ``# Call DFS for each child``        ``DFS(child, node, Val);`` ` `        ``# Taking bitwise OR of the``        ``# answer of the child to``        ``# find node's OR value``        ``answer[node] ``=` `(answer[node]``                        ``| answer[child]);``    ` `# Function to call DFS from the'=``# root for precomputing answers``def` `preprocess( Val):` `    ``DFS(``1``, ``-``1``, Val);` `# Function to calculate and print``# the Bitwise OR for Q queries``def` `findSubtreeOR(Queries, Q, Val):` `    ``# Perform preprocessing``    ``preprocess(Val);`` ` `    ``# Iterate over each given query``    ``for` `i ``in` `range``(Q):``        ` `        ``print``(answer[Queries[i]], end``=``' '``)``  ` `# Utility function to find and``# print bitwise OR for Q queries``def` `findSubtreeORUtil( N, Edges, Val, Queries, Q):` `    ``# Function to add edges to graph``    ``addEdgesToGraph(Edges, N);`` ` `    ``# Function call``    ``findSubtreeOR(Queries, Q, Val);`` ` `# Driver Code``if` `__name__``=``=``'__main__'``:``    ` `    ``# Number of nodes``    ``N ``=` `5``;``    ``Edges ``=` `[ [ ``1``, ``2` `], [ ``1``, ``3` `], [ ``3``, ``4` `], [ ``3``, ``5` `] ];`` ` `    ``Val ``=` `[ ``0``, ``2``, ``3``, ``4``, ``8``, ``16` `];``    ``Queries ``=` `[ ``2``, ``3``, ``1` `];`` ` `    ``Q ``=` `len``(Queries)`` ` `    ``# Function call``    ``findSubtreeORUtil(N, Edges, Val,Queries, Q);` `    ``# This code is contributed by rutvik_56`

## C#

 `// C# program to generate``// n-bit Gray codes``using` `System;``using` `System.Collections.Generic;``class` `GFG``{` `  ``// Maximum Number of nodes``  ``static` `int` `N = (``int``)1e5 + 5;` `  ``// Adjacency list``  ``static` `List > adj;` `  ``// Stores Bitwise OR of each node``  ``static` `int``[] answer;` `  ``// Function to Add edges to the Tree``  ``static` `void` `AddEdgesToGraph(``int``[, ] Edges, ``int` `N)``  ``{` `    ``// Traverse the edges``    ``for` `(``int` `i = 0; i < N - 1; i++) {``      ``int` `u = Edges[i, 0];``      ``int` `v = Edges[i, 1];` `      ``// Add edges``      ``adj[u].Add(v);``      ``adj[v].Add(u);``    ``}``  ``}` `  ``// Function to perform DFS``  ``// Traversal on the given tree``  ``static` `void` `DFS(``int` `node, ``int` `parent, ``int``[] Val)``  ``{` `    ``// Initialize answer with bitwise``    ``// OR of current node``    ``answer[node] = Val[node];` `    ``// Iterate over each child``    ``// of the current node``    ``foreach``(``int` `child ``in` `adj[node])``    ``{` `      ``// Skip parent node``      ``if` `(child == parent)``        ``continue``;` `      ``// Call DFS for each child``      ``DFS(child, node, Val);` `      ``// Taking bitwise OR of the``      ``// answer of the child to``      ``// find node's OR value``      ``answer[node] = (answer[node] | answer[child]);``    ``}``  ``}` `  ``// Function to call DFS from the'=``  ``// root for precomputing answers``  ``static` `void` `preprocess(``int``[] Val) { DFS(1, -1, Val); }` `  ``// Function to calculate and print``  ``// the Bitwise OR for Q queries``  ``static` `void` `findSubtreeOR(``int``[] Queries, ``int` `Q,``                            ``int``[] Val)``  ``{` `    ``// Perform preprocessing``    ``preprocess(Val);` `    ``// Iterate over each given query``    ``for` `(``int` `i = 0; i < Q; i++) {``      ``Console.Write(answer[Queries[i]] + ``" "``);``    ``}``  ``}` `  ``// Utility function to find and``  ``// print bitwise OR for Q queries``  ``static` `void` `findSubtreeORUtil(``int` `N, ``int``[, ] Edges,``                                ``int``[] Val, ``int``[] Queries,``                                ``int` `Q)``  ``{` `    ``// Function to Add edges to graph``    ``AddEdgesToGraph(Edges, N);` `    ``// Function call``    ``findSubtreeOR(Queries, Q, Val);``  ``}` `  ``// Driver function``  ``public` `static` `void` `Main(String[] args)``  ``{` `    ``adj = ``new` `List >();``    ``for` `(``int` `i = 0; i < N; i++)``      ``adj.Add(``new` `List<``int``>());``    ``answer = ``new` `int``[N];``    ``N = 5;``    ``int``[, ] Edges``      ``= { { 1, 2 }, { 1, 3 }, { 3, 4 }, { 3, 5 } };` `    ``int``[] Val = { 0, 2, 3, 4, 8, 16 };``    ``int``[] Queries = { 2, 3, 1 };``    ``int` `Q = Queries.Length;` `    ``// Function call``    ``findSubtreeORUtil(N, Edges, Val, Queries, Q);``  ``}``}` `// This code is contributed by grand_master.`

## Javascript

 ``
Output:
`3 28 31`

Time Complexity: O(N + Q)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up