Skip to content
Related Articles

Related Articles

XOR of all the nodes in the sub-tree of the given node
  • Difficulty Level : Medium
  • Last Updated : 25 Mar, 2020

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Adjacency list of the graph
vector<vector<int> > graph;
  
// Value of the node
vector<int> values, xor_values;
  
// Function to pre-compute the xor values
int pre_compute_xor(int i, int prev)
{
    // xor of the sub-tree
    int x = values[i];
  
    for (int j = 0; j < graph[i].size(); j++)
        if (graph[i][j] != prev) {
  
            // xor x with xor of the sub-tree
            // of it child nodes
            x ^= pre_compute_xor(graph[i][j], i);
        }
  
    xor_values[i] = x;
  
    // Return the xor
    return x;
}
  
// Function to return the xor of
// the nodes of the sub-tree
// rooted at node u
int query(int u)
{
    return xor_values[u];
}
  
// Driver code
int main()
{
    int n = 7;
  
    graph.resize(n);
    xor_values.resize(n);
  
    // Create the graph
    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);
  
    // Set the values of the nodes
    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-computation
    pre_compute_xor(0, -1);
  
    // Perform queries
    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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG
{
      
static int n = 7;
  
// Adjacency list of the graph
static Vector<Integer> []graph = new Vector[n];
  
// Value of the node
static Vector<Integer> values = new Vector<Integer>(),
xor_values = new Vector<Integer>(n);
  
// Function to pre-compute the xor values
static int pre_compute_xor(int i, int prev)
{
    // xor of the sub-tree
    int x = values.get(i);
  
    for (int j = 0; j < graph[i].size(); j++)
        if (graph[i].get(j)!= prev)
        {
  
            // xor x with xor of the sub-tree
            // of it child nodes
            x ^= pre_compute_xor(graph[i].get(j), i);
        }
    xor_values.remove(i);
    xor_values.add(i, x);
  
    // Return the xor
    return x;
}
  
// Function to return the xor of
// the nodes of the sub-tree
// rooted at node u
static int query(int u)
{
    return xor_values.get(u);
}
  
// Driver code
public static void main(String[] args)
{
      
    for(int i = 0; i < n; i++) 
    {
        graph[i] = new Vector<Integer>();
        xor_values.add(0);
    }
      
    // Create the graph
    graph[0].add(1);
    graph[0].add(2);
    graph[1].add(3);
    graph[1].add(4);
    graph[2].add(5);
    graph[2].add(6);
  
    // Set the values of the nodes
    values.add(1);
    values.add(2);
    values.add(3);
    values.add(4);
    values.add(5);
    values.add(6);
    values.add(7);
  
    // Pre-computation
    pre_compute_xor(0, -1);
  
    // Perform queries
    int queries[] = { 0, 1, 4, 5 };
    int q = queries.length;
    for (int i = 0; i < q; i++)
        System.out.print(query(queries[i]) +"\n");
}
}
  
// This code is contributed by Rajput-Ji

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
  
# Adjacency list of the graph 
graph = [] 
  
# Value of the node 
values = [] 
xor_values = [] 
  
# Function to pre-compute the xor values 
def pre_compute_xor(i, prev): 
  
    # xor of the sub-tree 
    x = values[i] 
  
    for j in range(len(graph[i])): 
        if graph[i][j] != prev: 
  
            # xor x with xor of the sub-tree 
            # of it child nodes 
            x ^= pre_compute_xor(graph[i][j], i) 
  
    xor_values[i] =
  
    # Return the xor 
    return
  
# Function to return the xor of 
# the nodes of the sub-tree 
# rooted at node u 
def query(u): 
  
    return xor_values[u] 
  
# Driver code 
n = 7
for i in range(n):
    graph.append([])
    xor_values.append(0
  
# Create the graph 
graph[0].append(1
graph[0].append(2
graph[1].append(3
graph[1].append(4
graph[2].append(5
graph[2].append(6
  
# Set the values of the nodes 
values.append(1
values.append(2
values.append(3
values.append(4
values.append(5
values.append(6
values.append(7
  
# Pre-computation 
pre_compute_xor(0, -1
  
# Perform queries 
queries = [ 0, 1, 4, 5
q = len(queries) 
for i in range(q): 
    print(query(queries[i])) 
  
# This code is contributed by divyamohan123

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
using System.Collections.Generic;
  
class GFG
{
       
static int n = 7;
   
// Adjacency list of the graph
static List<int> []graph = new List<int>[n];
   
// Value of the node
static List<int> values = new List<int>(),
xor_values = new List<int>(n);
   
// Function to pre-compute the xor values
static int pre_compute_xor(int i, int prev)
{
    // xor of the sub-tree
    int x = values[i];
   
    for (int j = 0; j < graph[i].Count; j++)
        if (graph[i][j] != prev)
        {
   
            // xor x with xor of the sub-tree
            // of it child nodes
            x ^= pre_compute_xor(graph[i][j], i);
        }
    xor_values.RemoveAt(i);
    xor_values.Insert(i, x);
   
    // Return the xor
    return x;
}
   
// Function to return the xor of
// the nodes of the sub-tree
// rooted at node u
static int query(int u)
{
    return xor_values[u];
}
   
// Driver code
public static void Main(String[] args)
{
       
    for(int i = 0; i < n; i++) 
    {
        graph[i] = new List<int>();
        xor_values.Add(0);
    }
       
    // Create the graph
    graph[0].Add(1);
    graph[0].Add(2);
    graph[1].Add(3);
    graph[1].Add(4);
    graph[2].Add(5);
    graph[2].Add(6);
   
    // Set the values of the nodes
    values.Add(1);
    values.Add(2);
    values.Add(3);
    values.Add(4);
    values.Add(5);
    values.Add(6);
    values.Add(7);
   
    // Pre-computation
    pre_compute_xor(0, -1);
   
    // Perform queries
    int []queries = { 0, 1, 4, 5 };
    int q = queries.Length;
    for (int i = 0; i < q; i++)
        Console.Write(query(queries[i]) +"\n");
}
}
  
// This code is contributed by PrinciRaj1992

chevron_right


Output:

0
3
5
6

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.

My Personal Notes arrow_drop_up
Recommended Articles
Page :