XOR of all the nodes in the sub-tree of the given node
Given an n-ary tree and Q queries where each query consists of an integer u which denotes a node. The task is to print the xor of all the values of nodes in the sub-tree of the given node.
Examples:
Input:
q[] = {0, 1, 4, 5}
Output:
0
3
5
6
Query 1: (1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7) = 0
Query 2: (2 ^ 4 ^ 5) = 3
Query 3: (5) = 5
Query 4: (6) = 6
Naive approach: For each node we have to traverse the tree for every query find the xor of all the nodes of the sub-tree. So the complexity of the code will be O(N * Q).
Efficient approach: If we pre-compute the xor of all the nodes of the sub-tree by traversing the total tree once and first computing the xor of all the nodes of the sub-tree of the child node first and then using the value of the child node for computing the xor of all the nodes of the sub-tree of the parent node. In this way we can compute the xor in O(N) time and store them for queries. When a query is asked we will print the pre-computed value in O(1) time.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector<vector< int > > graph;
vector< int > values, xor_values;
int pre_compute_xor( int i, int prev)
{
int x = values[i];
for ( int j = 0; j < graph[i].size(); j++)
if (graph[i][j] != prev) {
x ^= pre_compute_xor(graph[i][j], i);
}
xor_values[i] = x;
return x;
}
int query( int u)
{
return xor_values[u];
}
int main()
{
int n = 7;
graph.resize(n);
xor_values.resize(n);
graph[0].push_back(1);
graph[0].push_back(2);
graph[1].push_back(3);
graph[1].push_back(4);
graph[2].push_back(5);
graph[2].push_back(6);
values.push_back(1);
values.push_back(2);
values.push_back(3);
values.push_back(4);
values.push_back(5);
values.push_back(6);
values.push_back(7);
pre_compute_xor(0, -1);
int queries[] = { 0, 1, 4, 5 };
int q = sizeof (queries) / sizeof (queries[0]);
for ( int i = 0; i < q; i++)
cout << query(queries[i]) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int n = 7 ;
static Vector<Integer> []graph = new Vector[n];
static Vector<Integer> values = new Vector<Integer>(),
xor_values = new Vector<Integer>(n);
static int pre_compute_xor( int i, int prev)
{
int x = values.get(i);
for ( int j = 0 ; j < graph[i].size(); j++)
if (graph[i].get(j)!= prev)
{
x ^= pre_compute_xor(graph[i].get(j), i);
}
xor_values.remove(i);
xor_values.add(i, x);
return x;
}
static int query( int u)
{
return xor_values.get(u);
}
public static void main(String[] args)
{
for ( int i = 0 ; i < n; i++)
{
graph[i] = new Vector<Integer>();
xor_values.add( 0 );
}
graph[ 0 ].add( 1 );
graph[ 0 ].add( 2 );
graph[ 1 ].add( 3 );
graph[ 1 ].add( 4 );
graph[ 2 ].add( 5 );
graph[ 2 ].add( 6 );
values.add( 1 );
values.add( 2 );
values.add( 3 );
values.add( 4 );
values.add( 5 );
values.add( 6 );
values.add( 7 );
pre_compute_xor( 0 , - 1 );
int queries[] = { 0 , 1 , 4 , 5 };
int q = queries.length;
for ( int i = 0 ; i < q; i++)
System.out.print(query(queries[i]) + "\n" );
}
}
|
Python3
graph = []
values = []
xor_values = []
def pre_compute_xor(i, prev):
x = values[i]
for j in range ( len (graph[i])):
if graph[i][j] ! = prev:
x ^ = pre_compute_xor(graph[i][j], i)
xor_values[i] = x
return x
def query(u):
return xor_values[u]
n = 7
for i in range (n):
graph.append([])
xor_values.append( 0 )
graph[ 0 ].append( 1 )
graph[ 0 ].append( 2 )
graph[ 1 ].append( 3 )
graph[ 1 ].append( 4 )
graph[ 2 ].append( 5 )
graph[ 2 ].append( 6 )
values.append( 1 )
values.append( 2 )
values.append( 3 )
values.append( 4 )
values.append( 5 )
values.append( 6 )
values.append( 7 )
pre_compute_xor( 0 , - 1 )
queries = [ 0 , 1 , 4 , 5 ]
q = len (queries)
for i in range (q):
print (query(queries[i]))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int n = 7;
static List< int > []graph = new List< int >[n];
static List< int > values = new List< int >(),
xor_values = new List< int >(n);
static int pre_compute_xor( int i, int prev)
{
int x = values[i];
for ( int j = 0; j < graph[i].Count; j++)
if (graph[i][j] != prev)
{
x ^= pre_compute_xor(graph[i][j], i);
}
xor_values.RemoveAt(i);
xor_values.Insert(i, x);
return x;
}
static int query( int u)
{
return xor_values[u];
}
public static void Main(String[] args)
{
for ( int i = 0; i < n; i++)
{
graph[i] = new List< int >();
xor_values.Add(0);
}
graph[0].Add(1);
graph[0].Add(2);
graph[1].Add(3);
graph[1].Add(4);
graph[2].Add(5);
graph[2].Add(6);
values.Add(1);
values.Add(2);
values.Add(3);
values.Add(4);
values.Add(5);
values.Add(6);
values.Add(7);
pre_compute_xor(0, -1);
int []queries = { 0, 1, 4, 5 };
int q = queries.Length;
for ( int i = 0; i < q; i++)
Console.Write(query(queries[i]) + "\n" );
}
}
|
Javascript
<script>
let n = 7;
let graph = new Array(n);
let values = new Array();
let xor_values = new Array(n);
function pre_compute_xor(i, prev) {
let x = values[i];
for (let j = 0; j < graph[i].length; j++)
if (graph[i][j] != prev) {
x ^= pre_compute_xor(graph[i][j], i);
}
xor_values.splice(i, 1);
xor_values.splice(i, 0, x);
return x;
}
function query(u) {
return xor_values[u];
}
for (let i = 0; i < n; i++) {
graph[i] = new Array();
xor_values.push(0);
}
graph[0].push(1);
graph[0].push(2);
graph[1].push(3);
graph[1].push(4);
graph[2].push(5);
graph[2].push(6);
values.push(1);
values.push(2);
values.push(3);
values.push(4);
values.push(5);
values.push(6);
values.push(7);
pre_compute_xor(0, -1);
let queries = [0, 1, 4, 5];
let q = queries.length;
for (let i = 0; i < q; i++)
document.write(query(queries[i]) + "<br>" );
</script>
|
Time Complexity: O(n), where n is the number of nodes in the graph. This is because the pre_compute_xor function visits each node of the graph exactly once in a depth-first search fashion. The query function takes constant time since it just returns the pre-computed XOR value of the given node.
Auxiliary space: O(n), where n is the number of nodes in the graph. This is because we are using vectors to store the adjacency list of the graph, the values and XOR values of each node. Additionally, the depth of the recursion stack in the pre_compute_xor function can be up to O(n) in the worst case, which contributes to the space complexity.
Last Updated :
06 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...