# Perform the given queries on the rooted tree

• Difficulty Level : Hard
• Last Updated : 05 Oct, 2021

Given a rooted tree and not necessarily binary. The tree contains N nodes, labeled 1 to N. You are given the tree in the form of an array A[1..N] of size N. A[i] denotes label of the parent of node labeled i. For clarity, you may assume that the tree satisfies the following conditions.

• The root of the tree is labeled 1. Hence A[1] is set to 0.
• The parent of node T will always have a label less than T.

The task is to perform the following operations according to the type of query given.

1. ADD, X, Y: add Y to the value at node X.
2. ADDUP, X, Y: add Y to the value at node X. Then, add Y to the value at A[X] (i.e. the parent of X). The, add Y to the value at A[A[X]] (i.e. the parent of A[X]).. and so on, till you add Y to the value at root.

After you have performed all the given operations, you are asked to answer several queries of the following type

1. VAL, X: print the value at node X.
2. VALTREE, X: print the sum of values at all nodes in the subtree rooted at X (including X).

Source: Directi Interview | Set 13
Examples:

Input:
N = 7, M = 4, Q = 5
0 1 2 2 2 1 2
VALTREE 1
VALTREE 5
VAL 5
VALTREE 2
VAL 2
Output:
291

107
59
Input:
N = 5, M = 5, Q = 3
0 1 1 1 3
VAL 3
VALTREE 3
VALTREE 1
Output:
80
130
250

Explanation: This problem is a slight variation of dfs. In this, we have stored the node’s original value and addup value in the vector of the pair. We did 2 times dfs.

1. dfs1 for offline queries i.e to calculate the addup sum for each node.
2. dfs2 to store the subtree sum in an array.

Now all the queries can be answered in a constant time.
Graph before dfs1

Graph after dfs1

Below is the required implementation:

## C++

 `// C++ implementation to perform``// above operations and queries``#include ``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 > 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 > > 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 > 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 p = ``new` `Vector();``    ``static` `Vector> adj = ``new` `Vector>();``    ` `    ``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());``        ``}``        ` `        ``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 v = ``new` `Vector();``        ``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 q = ``new` `Vector();``        ``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> p = ``new` `List>();``    ``static` `List> adj = ``new` `List>();``    ` `    ``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>> v = ``new` `List>>();``    ``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> q = ``new` `List>();``    ``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

 ``

Output:

```291
0
0
107
59```

Time Complexity: O(1) per query, O(N) for preprocessing is taken by dfs1() and dfs2() function.
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up