// 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.