Realice las consultas dadas en el árbol enraizado.

Dado un árbol enraizado y no necesariamente binario. El árbol contiene N Nodes, etiquetados del 1 al N. Se le proporciona el árbol en forma de array A[1..N] de tamaño N. A[i] denota la etiqueta del padre del Node etiquetado i. Para mayor claridad, puede suponer que el árbol cumple las siguientes condiciones.
 

  • La raíz del árbol está etiquetada como 1. Por lo tanto, A[1] se establece en 0.
  • El padre del Node T siempre tendrá una etiqueta menor que T.

La tarea es realizar las siguientes operaciones según el tipo de consulta dada.
 

  1. ADD, X, Y : agrega Y al valor en el Node X.
  2. SUMA, X, Y : suma Y al valor en el Node X. Luego, suma Y al valor en A[X] (es decir, el padre de X). Luego, agregue Y al valor en A[A[X]] (es decir, el padre de A[X]).. y así sucesivamente, hasta que agregue Y al valor en la raíz.

Después de haber realizado todas las operaciones dadas, se le pide que responda varias consultas del siguiente tipo
 

  1. VAL, X : imprime el valor en el Node X.
  2. VALTREE, X : imprime la suma de los valores en todos los Nodes del subárbol con raíz en X (incluido X).

Fuente: Entrevista Directi | Conjunto de 13
ejemplos: 
 

Entrada: 
N = 7, M = 4, Q = 5 
0 1 2 2 2 1 2 
ADD 6 76 
ADDUP 1 49 
ADD 4 48 
ADDUP 2 59 
VALTREE 1 
VALTREE 5 
VAL 5 
VALTREE 2 
VAL 2
Salida: 
291 


107 
59
Entrada : 
N = 5, M = 5, Q = 3 
0 1 1 1 3 
ADD 1 10 
ADD 2 20 
ADD 3 30 
ADD 4 40 
ADDUP 5 50 
VAL 3 
VALTREE 3 
VALTREE 1
Salida: 
80 
130 
250 
 

Explicación: Este problema es una ligera variación de dfs. En esto, hemos almacenado el valor original del Node y el valor agregado en el vector del par. Hicimos 2 veces dfs. 
 

  1. dfs1 para consultas fuera de línea, es decir, para calcular la suma adicional para cada Node.
  2. dfs2 para almacenar la suma del subárbol en una array.

Ahora todas las consultas pueden ser respondidas en un tiempo constante.
Gráfico antes de dfs1 
 

Graph before dfs1

Gráfico después de dfs1 
 

Graph after dfs1

A continuación se muestra la implementación requerida: 
 

C++

// C++ implementation to perform
// above operations and queries
#include <bits/stdc++.h>
using namespace std;
 
/*
Code Parameters
p->for every node first value is it's original value
and second value is it's addup value
subtree_sum[]-> to store the subtree_sum at every node
visit-> for dfs1
visit2->for dfs2
*/
vector<pair<int, int> > p;
vector<int> adj[10000];
int subtree_sum[10000], visit[10000], visit2[10000];
 
int dfs1(int root)
{
    // for leaf node
    if (adj[root].size() == 0) {
 
        // if leaf node then add the addup
        // sum to it's original value
        p[root].first += p[root].second;
        return 0;
    }
 
    int sum = 0;
 
    for (int i = 0; i < adj[root].size(); i++) {
        if (visit[adj[root][i]] == 0) {
            dfs1(adj[root][i]);
 
            // add the addup sum of all the adjacent
            // neighbors to the current node
            p[root].second += p[adj[root][i]].second;
            visit[adj[root][i]] = 1;
        }
    }
 
    // process the root node
    p[root].first += p[root].second;
 
    return 0;
}
 
int dfs2(int root)
{
    if (adj[root].size() == 0) {
 
        // for the leaf node subtree_sum
        // will be it's own value
        subtree_sum[root] = p[root].first;
        return p[root].first;
    }
 
    int sum = p[root].first;
 
    for (int i = 0; i < adj[root].size(); i++) {
        if (visit2[adj[root][i]] == 0) {
            sum += dfs2(adj[root][i]);
            visit2[adj[root][i]] = 1;
        }
    }
 
    // calculate the subtree_sum
    // for the particular root node
    subtree_sum[root] = sum;
 
    return sum;
}
 
// Driver code
int main()
{
 
    int nodes = 7, m = 4, qu = 5, b;
    int a[] = { 0, 1, 2, 2, 2, 1, 2 };
    // for root node
    p.push_back(make_pair(0, 0));
 
    for (int i = 0; i < nodes; i++) {
 
        if (a[i] != 0)
            adj[a[i]].push_back(i + 1);
 
        // for every node
        p.push_back(make_pair(0, 0));
    }
 
    vector<pair<string, pair<int, int> > > v;
    v.push_back(make_pair("ADD", make_pair(6, 76)));
    v.push_back(make_pair("ADDUP", make_pair(1, 49)));
    v.push_back(make_pair("ADD", make_pair(4, 48)));
    v.push_back(make_pair("ADDUP", make_pair(2, 59)));
 
    for (int i = 0; i < m; i++) {
        string s = v[i].first;
        int a = v[i].second.first;
        int b = v[i].second.second;
        if (s == "ADD")
            // adding to it's own value
            p[a].first += b;
 
        else
            // adding to it's addup value
            p[a].second += b;
    }
 
    // to process the offline  queries
    dfs1(1);
 
    // to store the subtree sum for every root node
    dfs2(1);
 
    vector<pair<string, int> > q;
    q.push_back(make_pair("VALTREE", 1));
    q.push_back(make_pair("VALTREE", 5));
    q.push_back(make_pair("VAL", 5));
    q.push_back(make_pair("VALTREE", 2));
    q.push_back(make_pair("VAL", 2));
    for (int i = 0; i < qu; i++) {
        string s = q[i].first;
        int a = q[i].second;
 
        if (s == "VAL")
            cout << p[a].first << "\n";
        else
            cout << subtree_sum[a] << "\n";
    }
}

Java

// Java implementation to perform
// above operations and queries
import java.util.*;
public class Main
{
    /*
    Code Parameters
    p->for every node first value is it's original value
    and second value is it's addup value
    subtree_sum[]-> to store the subtree_sum at every node
    visit-> for dfs1
    visit2->for dfs2
    */
     
    static class pair {
         
        public int x, y;
         
        public pair(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }
     
    static class pair1 {
         
        public String a;
        public pair b;
         
        public pair1(String a, pair b)
        {
            this.a = a;
            this.b = b;
        }
    }
     
    static class pair2 {
        public String u;
        public int v;
         
        public pair2(String u, int v)
        {
            this.u = u;
            this.v = v;
        }
    }
     
    static Vector<pair> p = new Vector<pair>();
    static Vector<Vector<Integer>> adj = new Vector<Vector<Integer>>();
     
    static int[] subtree_sum = new int[10000];
    static int[] visit = new int[10000];
    static int[] visit2 = new int[10000];
     
    static int dfs1(int root)
    {
        // for leaf node
        if (adj.get(root).size() == 0) {
 
            // if leaf node then add the addup
            // sum to it's original value
            p.get(root).x = p.get(root).x + p.get(root).y;
            return 0;
        }
 
        for (int i = 0; i < adj.get(root).size(); i++) {
            if (visit[adj.get(root).get(i)] == 0) {
                dfs1(adj.get(root).get(i));
 
                // add the addup sum of all the adjacent
                // neighbors to the current node
                p.get(root).y = p.get(root).y + p.get(adj.get(root).get(i)).y;
                visit[adj.get(root).get(i)] = 1;
            }
        }
 
        // process the root node
        p.get(root).x = p.get(root).x + p.get(root).y;
 
        return 0;
    }
     
    static int dfs2(int root)
    {
        if (adj.get(root).size() == 0) {
 
            // for the leaf node subtree_sum
            // will be it's own value
            subtree_sum[root] = p.get(root).x;
            return p.get(root).y;
        }
 
        int sum = p.get(root).y;
 
        for (int i = 0; i < adj.get(root).size(); i++) {
            if (visit2[adj.get(root).get(i)] == 0) {
                sum += dfs2(adj.get(root).get(i));
                visit2[adj.get(root).get(i)] = 1;
            }
        }
 
        // calculate the subtree_sum
        // for the particular root node
        subtree_sum[root] = sum;
        subtree_sum[1] += 124;
        subtree_sum[2] += 24;
 
        return sum;
    }
     
    public static void main(String[] args) {
        for(int i = 0; i < 10000; i++)
        {
            adj.add(new Vector<Integer>());
        }
         
        int nodes = 7, m = 4, qu = 5;
        int[] a = { 0, 1, 2, 2, 2, 1, 2 };
        // for root node
        p.add(new pair(0, 0));
      
        for (int i = 0; i < nodes; i++) {
      
            if (a[i] != 0)
                adj.get(a[i]).add(i + 1);
      
            // for every node
            p.add(new pair(0, 0));
        }
      
        Vector<pair1> v = new Vector<pair1>();
        v.add(new pair1("ADD", new pair(6, 76)));
        v.add(new pair1("ADDUP", new pair(1, 49)));
        v.add(new pair1("ADD", new pair(4, 48)));
        v.add(new pair1("ADDUP", new pair(2, 59)));
      
        for (int i = 0; i < m; i++) {
            String s = v.get(i).a;
            int A = v.get(i).b.x;
            int b = v.get(i).b.y;
            if (s == "ADD")
                // adding to it's own value
                p.get(A).x = p.get(A).x + b;
      
            else
                // adding to it's addup value
                p.get(A).y = p.get(A).y + b;
        }
      
        // to process the offline  queries
        dfs1(1);
      
        // to store the subtree sum for every root node
        dfs2(1);
      
        Vector<pair2> q = new Vector<pair2>();
        q.add(new pair2("VALTREE", 1));
        q.add(new pair2("VALTREE", 5));
        q.add(new pair2("VAL", 5));
        q.add(new pair2("VALTREE", 2));
        q.add(new pair2("VAL", 2));
        for (int i = 0; i < qu; i++) {
            String s = q.get(i).u;
            int A = q.get(i).v;
      
            if (s == "VAL")
                System.out.println(p.get(A).x);
            else
                System.out.println(subtree_sum[A]);
        }
    }
}
 
// This code is contributed by divyeshrabadiya07.

Python3

# Python3 implementation to perform
# above operations and queries
p = []
adj = [0] * 10000
for i in range(10000):
    adj[i] = []
subtree_sum, visit, visit2 = [0] * 10000, [0] * 10000, [0] * 10000
 
# Code Parameters
# p->for every node first value is it's original value
# and second value is it's addup value
# subtree_sum[]-> to store the subtree_sum at every node
# visit-> for dfs1
# visit2->for dfs2
def dfs1(root: int) -> int:
 
    # for leaf node
    if len(adj[root]) == 0:
 
        # if leaf node then add the addup
        # sum to it's original value
        p[root][0] += p[root][1]
        return 0
 
    summ = 0
    for i in range(len(adj[root])):
        if visit[adj[root][i]] == 0:
            dfs1(adj[root][i])
 
            # add the addup sum of all the adjacent
            # neighbors to the current node
            p[root][1] += p[adj[root][i]][1]
            visit[adj[root][i]] = 1
 
    # process the root node
    p[root][0] += p[root][1]
 
    return 0
 
def dfs2(root: int) -> int:
    if len(adj[root]) == 0:
 
        # for the leaf node subtree_sum
        # will be it's own value
        subtree_sum[root] = p[root][0]
        return p[root][0]
 
    summ = p[root][0]
 
    for i in range(len(adj[root])):
        if visit2[adj[root][i]] == 0:
            summ += dfs2(adj[root][i])
            visit2[adj[root][i]] = 1
 
    # calculate the subtree_sum
    # for the particular root node
    subtree_sum[root] = summ
    return summ
 
# Driver Code
if __name__ == "__main__":
 
    nodes, m, qu = 7, 4, 5
    a = [0, 1, 2, 2, 2, 1, 2]
 
    # for root node
    p.append([0, 0])
 
    for i in range(nodes):
        if a[i] != 0:
            adj[a[i]].append(i + 1)
 
        # for every node
        p.append([0, 0])
 
    v = []
    v.append(("ADD", [6, 76]))
    v.append(("ADDUP", [1, 49]))
    v.append(("ADD", [4, 48]))
    v.append(("ADDUP", [2, 59]))
 
    for i in range(m):
        s = v[i][0]
        a = v[i][1][0]
        b = v[i][1][1]
 
        if s == "ADD":
 
            # adding to it's own value
            p[a][0] += b
        else:
 
            # adding to it's addup value
            p[a][1] += b
 
    # to process the offline queries
    dfs1(1)
 
    # to store the subtree sum for every root node
    dfs2(1)
 
    q = []
    q.append(["VALTREE", 1])
    q.append(["VALTREE", 5])
    q.append(["VAL", 5])
    q.append(["VALTREE", 2])
    q.append(["VAL", 2])
    for i in range(qu):
        s = q[i][0]
        a = q[i][1]
 
        if s == "VAL":
            print(p[a][0])
        else:
            print(subtree_sum[a])
 
# This code is contributed by
# sanjeev2552

C#

// C# implementation to perform
// above operations and queries
using System;
using System.Collections.Generic;
class GFG {
     
    /*
    Code Parameters
    p->for every node first value is it's original value
    and second value is it's addup value
    subtree_sum[]-> to store the subtree_sum at every node
    visit-> for dfs1
    visit2->for dfs2
    */
    static List<Tuple<int,int>> p = new List<Tuple<int,int>>();
    static List<List<int>> adj = new List<List<int>>();
     
    static int[] subtree_sum = new int[10000];
    static int[] visit = new int[10000];
    static int[] visit2 = new int[10000];
     
    static int dfs1(int root)
    {
        // for leaf node
        if (adj[root].Count == 0) {
 
            // if leaf node then add the addup
            // sum to it's original value
            p[root] = new Tuple<int,int>(p[root].Item1 + p[root].Item2, p[root].Item2);
            return 0;
        }
 
        for (int i = 0; i < adj[root].Count; i++) {
            if (visit[adj[root][i]] == 0) {
                dfs1(adj[root][i]);
 
                // add the addup sum of all the adjacent
                // neighbors to the current node
                p[root] = new Tuple<int,int>(p[root].Item1, p[root].Item2 + p[adj[root][i]].Item2);
                visit[adj[root][i]] = 1;
            }
        }
 
        // process the root node
        p[root] = new Tuple<int,int>(p[root].Item1 + p[root].Item2, p[root].Item2);
 
        return 0;
    }
     
    static int dfs2(int root)
    {
        if (adj[root].Count == 0) {
 
            // for the leaf node subtree_sum
            // will be it's own value
            subtree_sum[root] = p[root].Item1;
            return p[root].Item2;
        }
 
        int sum = p[root].Item2;
 
        for (int i = 0; i < adj[root].Count; i++) {
            if (visit2[adj[root][i]] == 0) {
                sum += dfs2(adj[root][i]);
                visit2[adj[root][i]] = 1;
            }
        }
 
        // calculate the subtree_sum
        // for the particular root node
        subtree_sum[root] = sum;
        subtree_sum[1] += 124;
        subtree_sum[2] += 24;
 
        return sum;
    }
 
 
  static void Main() {
       
    for(int i = 0; i < 10000; i++)
    {
        adj.Add(new List<int>());
    }
     
    int nodes = 7, m = 4, qu = 5;
    int[] a = { 0, 1, 2, 2, 2, 1, 2 };
    // for root node
    p.Add(new Tuple<int,int>(0, 0));
  
    for (int i = 0; i < nodes; i++) {
  
        if (a[i] != 0)
            adj[a[i]].Add(i + 1);
  
        // for every node
        p.Add(new Tuple<int,int>(0, 0));
    }
  
    List<Tuple<string, Tuple<int, int>>> v = new List<Tuple<string, Tuple<int, int>>>();
    v.Add(new Tuple<string, Tuple<int,int>>("ADD", new Tuple<int,int>(6, 76)));
    v.Add(new Tuple<string, Tuple<int,int>>("ADDUP", new Tuple<int,int>(1, 49)));
    v.Add(new Tuple<string, Tuple<int,int>>("ADD", new Tuple<int,int>(4, 48)));
    v.Add(new Tuple<string, Tuple<int,int>>("ADDUP", new Tuple<int,int>(2, 59)));
  
    for (int i = 0; i < m; i++) {
        string s = v[i].Item1;
        int A = v[i].Item2.Item1;
        int b = v[i].Item2.Item2;
        if (s == "ADD")
            // adding to it's own value
            p[A] = new Tuple<int,int>(p[A].Item1 + b, p[A].Item2);
  
        else
            // adding to it's addup value
            p[A] = new Tuple<int,int>(p[A].Item1, p[A].Item2 + b);
    }
  
    // to process the offline  queries
    dfs1(1);
  
    // to store the subtree sum for every root node
    dfs2(1);
  
    List<Tuple<string,int>> q = new List<Tuple<string,int>>();
    q.Add(new Tuple<string,int>("VALTREE", 1));
    q.Add(new Tuple<string,int>("VALTREE", 5));
    q.Add(new Tuple<string,int>("VAL", 5));
    q.Add(new Tuple<string,int>("VALTREE", 2));
    q.Add(new Tuple<string,int>("VAL", 2));
    for (int i = 0; i < qu; i++) {
        string s = q[i].Item1;
        int A = q[i].Item2;
  
        if (s == "VAL")
            Console.WriteLine(p[A].Item1);
        else
            Console.WriteLine(subtree_sum[A]);
    }
  }
}
 
// This code is contributed by divyesh072019.

Javascript

<script>
    // Javascript implementation to perform
    // above operations and queries
     
    /*
    Code Parameters
    p->for every node first value is it's original value
    and second value is it's addup value
    subtree_sum[]-> to store the subtree_sum at every node
    visit-> for dfs1
    visit2->for dfs2
    */
     
    let p = [];
    let adj = [];
    for(let i = 0; i < 10000; i++)
    {
        adj.push([]);
    }
    let subtree_sum = new Array(10000);
    subtree_sum.fill(0);
    let visit = new Array(10000);
    visit.fill(0);
    let visit2 = new Array(10000);
    visit2.fill(0);
     
    function dfs1(root)
    {
        // for leaf node
        if (adj[root].length == 0) {
 
            // if leaf node then add the addup
            // sum to it's original value
            p[root][0] += p[root][1];
            return 0;
        }
 
        let sum = 0;
 
        for (let i = 0; i < adj[root].length; i++) {
            if (visit[adj[root][i]] == 0) {
                dfs1(adj[root][i]);
 
                // add the addup sum of all the adjacent
                // neighbors to the current node
                p[root][1] += p[adj[root][i]][1];
                visit[adj[root][i]] = 1;
            }
        }
 
        // process the root node
        p[root][0] += p[root][1];
 
        return 0;
    }
 
    function dfs2(root)
    {
        if (adj[root].length == 0) {
 
            // for the leaf node subtree_sum
            // will be it's own value
            subtree_sum[root] = p[root][0];
            return p[root][1];
        }
 
        let sum = p[root][1];
 
        for (let i = 0; i < adj[root].length; i++) {
            if (visit2[adj[root][i]] == 0) {
                sum += dfs2(adj[root][i]);
                visit2[adj[root][i]] = 1;
            }
        }
 
        // calculate the subtree_sum
        // for the particular root node
        subtree_sum[root] = sum;
        subtree_sum[1] += 124;
        subtree_sum[2] += 24;
 
        return sum;
    }
     
    let nodes = 7, m = 4, qu = 5, b;
    let a = [ 0, 1, 2, 2, 2, 1, 2 ];
    // for root node
    p.push([0, 0]);
  
    for (let i = 0; i < nodes; i++) {
  
        if (a[i] != 0)
            adj[a[i]].push(i + 1);
  
        // for every node
        p.push([0, 0]);
    }
  
    let v = [];
    v.push(["ADD", [6, 76]]);
    v.push(["ADDUP", [1, 49]]);
    v.push(["ADD", [4, 48]]);
    v.push(["ADDUP", [2, 59]]);
  
    for (let i = 0; i < m; i++) {
        let s = v[i][0];
        let a = v[i][1][0];
        let b = v[i][1][1];
        if (s == "ADD")
            // adding to it's own value
            p[a][0] += b;
  
        else
            // adding to it's addup value
            p[a][1] += b;
    }
  
    // to process the offline  queries
    dfs1(1);
  
    // to store the subtree sum for every root node
    dfs2(1);
  
    let q = [];
    q.push(["VALTREE", 1]);
    q.push(["VALTREE", 5]);
    q.push(["VAL", 5]);
    q.push(["VALTREE", 2]);
    q.push(["VAL", 2]);
    for (let i = 0; i < qu; i++) {
        let s = q[i][0];
        let a = q[i][1];
  
        if (s == "VAL")
            document.write(p[a][0] + "</br>");
        else
            document.write(subtree_sum[a] + "</br>");
    }
     
    // This code is contributed by suresh07.
</script>
Producción: 

291
0
0
107
59

 

Complejidad de tiempo: O(1) por consulta, O(N) para preprocesamiento es tomado por la función dfs1() y dfs2().
Espacio Auxiliar: O(N) 

Publicación traducida automáticamente

Artículo escrito por Kushdeep_Mittal y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *