In this HackerEarth Rooted trees problem solution, You are given a rooted tree of N nodes. Each node i contains a value ai. Initially, all values of the node are 0, your task is to process Q queries of the following two types:
  1. 0 v x for every node u in a subtree of v if au < Y add x to au
  2. 1 v print the value au
The tree is rooted at 1.


HackerEarth Rooted trees problem solution


HackerEarth Rooted trees problem solution.

import java.io.*;
import java.util.*;

public class MainJava{
static ArrayList<Integer>[] adj;
static int[] vals, par;
static int Y;
static void dfs(int u ,int p){
par[u]=p;
for(int v:adj[u]){
if(v!=p){
dfs(v,u);
}
}
}
static void Update(int u, int p,int x) {
if (vals[u] >= Y)
return;
vals[u] += x;
for (int v : adj[u]){
if(v!=p)
Update(v,u, x);
}
}

public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
PrintWriter pw = new PrintWriter(System.out);
int t = sc.nextInt();
while(t-->0){
int n = sc.nextInt();
int q = sc.nextInt();
Y = sc.nextInt();
adj = new ArrayList[n];
for (int i = 0; i < n; i++)
adj[i] = new ArrayList<>();

for (int i = 1; i < n; i++) {
int u = sc.nextInt() - 1;
int v = sc.nextInt() - 1;
adj[u].add(v);
adj[v].add(u);
}
vals = new int[n];
par = new int[n];
dfs(0,-1);

while (q-- > 0) {

if (sc.nextInt() == 0) {
int v = sc.nextInt() - 1;
int x = sc.nextInt();
Update(v,par[v], x);
} else {
pw.println(vals[sc.nextInt() - 1]);
}
}
}


pw.flush();
}


static class Scanner {
BufferedReader br;
StringTokenizer st;

public Scanner(InputStream s) {
br = new BufferedReader(new InputStreamReader(s));
}

public Scanner(FileReader f) {
br = new BufferedReader(f);
}

public String next() throws IOException {
while (st == null || !st.hasMoreTokens())
st = new StringTokenizer(br.readLine());
return st.nextToken();
}

public String nextLine() throws IOException {
return br.readLine();
}

public int nextInt() throws IOException {
return Integer.parseInt(next());
}

public long nextLong() throws IOException {
return Long.parseLong(next());
}

public double nextDouble() throws IOException {
return Double.parseDouble(next());
}

public int[] nextIntArr(int n) throws IOException {
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(next());
}
return arr;
}

public boolean ready() throws IOException {
return br.ready();
}
}

}

Second solution

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 1e5 + 14;
int n, y, q, st[N], en[N], a[N], ver[N];
vector<int> g[N];
set<int> ley;

void dfs(int v = 0, int p = -1) {
static int time;
if (p == -1)
time = 0;
ver[time] = v;
st[v] = time++;
for (auto u : g[v])
if (u != p)
dfs(u, v);
en[v] = time;
}

int main() {
ios::sync_with_stdio(0), cin.tie(0);
int t;
cin >> t;
while (t--) {
cin >> n >> q >> y;
fill(g, g + n, vector<int>());
fill(a, a + n, 0);
for (int i = 0; i < n - 1; ++i) {
int v, u;
cin >> v >> u;
--v;
--u;
g[v].push_back(u);
g[u].push_back(v);
}
ley.clear();
for (int i = 0; i < n; ++i)
ley.insert(ley.begin(), i);
dfs();
while (q--) {
int t, v;
cin >> t >> v;
--v;
if (t == 0) {
int x;
cin >> x;
auto it = ley.lower_bound(st[v]);
while (it != ley.end() && *it < en[v]) {
int u = ver[*it];
a[u] += x;
if (a[u] >= y)
it = ley.erase(it);
else
++it;
}
}
else
cout << a[v] << '\n';
}
}
}