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

📅  最后修改于: 2021-10-25 04:53:36             🧑  作者: 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


Javascript


输出:
0
3
5
6

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程