📌  相关文章
📜  给定节点的子树中所有节点的XOR

📅  最后修改于: 2021-05-04 19:17:41             🧑  作者: Mango

给定一个n元树和Q个查询,其中每个查询都由表示节点的整数u组成。任务是打印给定节点的子树中所有节点值的异或。

例子:

天真的方法:对于每个节点,我们必须遍历每个查询的树,以找到子树所有节点的异或。因此,代码的复杂度将为O(N * Q)

高效的方法:如果我们先遍历整个树,然后首先计算子节点的子树的所有节点的异或,然后使用的值来预先计算子树的所有节点的异或子节点,用于计算父节点子树的所有节点的异或。这样,我们可以计算O(N)时间的异或并将其存储以进行查询。当询问查询时,我们将在O(1)时间中打印预先计算的值。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
// Adjacency list of the graph
vector > graph;
  
// Value of the node
vector 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;
}


Java
// Java implementation of the approach
import java.util.*;
  
class GFG
{
      
static int n = 7;
  
// Adjacency list of the graph
static Vector []graph = new Vector[n];
  
// Value of the node
static Vector values = new Vector(),
xor_values = new Vector(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();
        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


Python3
# 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] = x 
  
    # Return the xor 
    return x 
  
# 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


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
  
class GFG
{
       
static int n = 7;
   
// Adjacency list of the graph
static List []graph = new List[n];
   
// Value of the node
static List values = new List(),
xor_values = new List(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();
        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


输出:
0
3
5
6