BackhardGraphsRazorpayZomato

Quantum Network Stream Validator 4 Solution

Problem Statement

Quantum Network Stream Validator 4

You are given a rooted tree with N nodes (1 ≤ N ≤ 10^5). Each node i carries an integer value a_i that represents the quantum state of that node. After the tree is constructed, you must answer Q queries (1 ≤ Q ≤ 10^5). Each query supplies two nodes u and v and a threshold T. For the simple path that connects u and v, determine whether the maximum value among all nodes on that path is less than or equal to T. If the condition holds, output "YES"; otherwise output "NO".

Input format:

  • The first line contains the integer N.
  • The next N−1 lines each contain two integers x and y, denoting an undirected edge between nodes x and y.
  • The following line contains N integers a_1, a_2, …, a_N.
  • The next line contains the integer Q.
  • The following Q lines each contain three integers u, v, T.

Output format: For each query, print a single line containing either "YES" or "NO".

The task requires an efficient solution that can handle the maximum constraints. Heavy‑Light Decomposition is a suitable technique to answer each query in O(log N) time after an O(N) preprocessing step.

Example 1
Input
5 1 2 1 3 3 4 3 5 3 1 4 2 5 3 1 5 4 2 4 3 4 5 5
Output
NO NO YES

Explanation: The tree is: 1─2 │ 3─4 │ 5 Values: 1→3, 2→1, 3→4, 4→2, 5→5. Query 1: path 1‑5 is 1‑3‑5 with values 3,4,5. Max=5 >4 → NO. Query 2: path 2‑4 is 2‑1‑3‑4 with values 1,3,4,2. Max=4 >3 → NO. Query 3: path 4‑5 is 4‑3‑5 with values 2,4,5. Max=5 ≤5 → YES.

Example 2
Input
3 1 2 2 3 10 20 15 2 1 3 20 2 3 15
Output
YES NO

Explanation: Tree: 1─2─3. Values: 1→10, 2→20, 3→15. Query 1: path 1‑3 is 1‑2‑3, values 10,20,15. Max=20 ≤20 → YES. Query 2: path 2‑3 is 2‑3, values 20,15. Max=20 >15 → NO.

Example 3
Input
6 1 2 1 3 2 4 2 5 5 6 5 3 8 2 7 1 4 4 6 7 3 4 8 1 6 5 2 5 6
Output
YES YES NO NO

Explanation: Tree structure: 1─2─4 │ 3 │ 5─6 Values: 1→5, 2→3, 3→8, 4→2, 5→7, 6→1. Query 1: 4‑6 path 4‑2‑5‑6 values 2,3,7,1. Max=7 ≤7 → YES. Query 2: 3‑4 path 3‑1‑2‑4 values 8,5,3,2. Max=8 ≤8 → YES. Query 3: 1‑6 path 1‑2‑5‑6 values 5,3,7,1. Max=7 >5 → NO. Query 4: 2‑5 path 2‑5 values 3,7. Max=7 >6 → NO.

Constraints

  • 1 ≤ N ≤ 10^5
  • 1 ≤ Q ≤ 10^5
  • 1 ≤ a_i ≤ 10^9
  • 1 ≤ T ≤ 10^9
  • The graph is a tree (connected and acyclic)
Live Compiler1 Free Run Available
Loading Editor...
Test Cases & Output
Click "Run" to test your 1 free compile trial!

🚀 Practice this problem

Run code, get AI hints & track streak

Sign Up Free

Quantum Network Stream Validator 4 — Problem Statement & Solution Guide

GraphsHardHeavy-Light Decomposition
TimeO((N + Q) log^2 N)
|
SpaceO(N)

Problem Description

Quantum Network Stream Validator 4

You are given a rooted tree with N nodes (1 ≤ N ≤ 10^5). Each node i carries an integer value a_i that represents the quantum state of that node. After the tree is constructed, you must answer Q queries (1 ≤ Q ≤ 10^5). Each query supplies two nodes u and v and a threshold T. For the simple path that connects u and v, determine whether the maximum value among all nodes on that path is less than or equal to T. If the condition holds, output "YES"; otherwise output "NO".

Input format:

- The first line contains the integer N.

- The next N−1 lines each contain two integers x and y, denoting an undirected edge between nodes x and y.

- The following line contains N integers a_1, a_2, …, a_N.

- The next line contains the integer Q.

- The following Q lines each contain three integers u, v, T.

Output format:

For each query, print a single line containing either "YES" or "NO".

The task requires an efficient solution that can handle the maximum constraints. Heavy‑Light Decomposition is a suitable technique to answer each query in O(log N) time after an O(N) preprocessing step.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Quantum Network Stream Validator 4"

hard

WHY DOES IT MATTER?

This pattern is essential for solving path queries on trees efficiently. It is a cornerstone of advanced graph algorithms and is frequently tested in high-level technical interviews at top-tier companies.

OPTIMIZATION CHALLENGE

The key insight is decomposing the tree into heavy paths to ensure that any path query can be broken into O(log N) contiguous segments in an array, allowing the use of efficient range query data structures.

REAL-WORLD CONNECTION

Analogous to routing packets in a network where you need to find the maximum bandwidth bottleneck on a path between two servers. HLD helps in breaking down the path into manageable segments for efficient analysis.

In interviews, clearly explain the decomposition step and how the segment tree is built on the Euler tour array. Emphasize the O(log^2 N) complexity and why it is optimal for this problem.

COMPLEXITY AT A GLANCE

⏱ Time:O((N + Q) log^2 N)
💾 Space:O(N)

Core Theory — Why This Approach?

The problem requires answering multiple path queries on a static tree, specifically checking if the maximum value on the path between two nodes exceeds a threshold. A naive approach would involve traversing the path for each query, which takes O(N) time per query, leading to O(NQ) total time. This is infeasible for N, Q up to 10^5. The optimal paradigm is Heavy-Light Decomposition (HLD) combined with a Segment Tree or Binary Indexed Tree (BIT) for range maximum queries. HLD decomposes the tree into heavy paths, ensuring that any path between two nodes can be decomposed into O(log N) contiguous segments in the Euler tour array. Each segment can be queried in O(log N) time using a segment tree, resulting in O(log^2 N) per query.

Interview Questions on This Problem

Q1Why is Heavy-Light Decomposition preferred over Binary Lifting for path maximum queries?

Binary Lifting is efficient for LCA and path sums if the operation is associative and invertible (like sum), but for maximum, it is not straightforward to combine partial paths without visiting all nodes. HLD allows decomposing the path into O(log N) contiguous segments in an array, enabling efficient range maximum queries using standard data structures like Segment Trees.

Q2How do you handle the case where the path goes through the LCA in HLD?

In HLD, you lift the deeper node until both nodes are in the same heavy chain. If they are not, you query the segment from the current node to the head of its chain, then move to the parent of the head. Once both nodes are in the same chain, you query the segment between them. The LCA is implicitly handled by the lifting process.

Q3What is the time complexity of a single path maximum query using HLD and a Segment Tree?

The time complexity is O(log^2 N). The path is decomposed into O(log N) segments, and each segment query on the Segment Tree takes O(log N) time.

Examples

Example 1

Input

5
1 2
1 3
3 4
3 5
3 1 4 2 5
3
1 5 4
2 4 3
4 5 5

Output

NO
NO
YES

Explanation: The tree is: 1─2 │ 3─4 │ 5 Values: 1→3, 2→1, 3→4, 4→2, 5→5. Query 1: path 1‑5 is 1‑3‑5 with values 3,4,5. Max=5 >4 → NO. Query 2: path 2‑4 is 2‑1‑3‑4 with values 1,3,4,2. Max=4 >3 → NO. Query 3: path 4‑5 is 4‑3‑5 with values 2,4,5. Max=5 ≤5 → YES.

Example 2

Input

3
1 2
2 3
10 20 15
2
1 3 20
2 3 15

Output

YES
NO

Explanation: Tree: 1─2─3. Values: 1→10, 2→20, 3→15. Query 1: path 1‑3 is 1‑2‑3, values 10,20,15. Max=20 ≤20 → YES. Query 2: path 2‑3 is 2‑3, values 20,15. Max=20 >15 → NO.

Example 3

Input

6
1 2
1 3
2 4
2 5
5 6
5 3 8 2 7 1
4
4 6 7
3 4 8
1 6 5
2 5 6

Output

YES
YES
NO
NO

Explanation: Tree structure: 1─2─4 │ 3 │ 5─6 Values: 1→5, 2→3, 3→8, 4→2, 5→7, 6→1. Query 1: 4‑6 path 4‑2‑5‑6 values 2,3,7,1. Max=7 ≤7 → YES. Query 2: 3‑4 path 3‑1‑2‑4 values 8,5,3,2. Max=8 ≤8 → YES. Query 3: 1‑6 path 1‑2‑5‑6 values 5,3,7,1. Max=7 >5 → NO. Query 4: 2‑5 path 2‑5 values 3,7. Max=7 >6 → NO.

Constraints

  • 1 ≤ N ≤ 10^5
  • 1 ≤ Q ≤ 10^5
  • 1 ≤ a_i ≤ 10^9
  • 1 ≤ T ≤ 10^9
  • The graph is a tree (connected and acyclic)

Optimal Approach & Strategy

Use Heavy-Light Decomposition to decompose the path into O(log N) contiguous segments in the Euler tour array. Use a Segment Tree to answer range maximum queries on these segments in O(log N) time each, resulting in O(log^2 N) per query.

Brute Force Approach

For each query, traverse the path from u to v by finding the LCA and walking up from both nodes, keeping track of the maximum value. This takes O(N) time per query, leading to O(NQ) total time.

Verified Code Solutions

JavaScript Solution
Time: O((N + Q) log^2 N)
function heavyLightDecomposition(graph) {
   // Initialize variables to store the result and the heavy-light decomposition
   let result = 0;
   let heavyLightDecomposition = {};

   // Function to find the root of a node in the heavy-light decomposition
   function findRoot(node) {
      if (heavyLightDecomposition[node] === node) {
         return node;
      }
      return findRoot(heavyLightDecomposition[node]);
   }

   // Function to merge two nodes in the heavy-light decomposition
   function mergeNodes(node1, node2) {
      let root1 = findRoot(node1);
      let root2 = findRoot(node2);

      if (root1 !== root2) {
         heavyLightDecomposition[root1] = root2;
      }
   }

   // Function to calculate the result using the heavy-light decomposition
   function calculateResult() {
      // Initialize variables to store the result and the heavy-light decomposition
      let result = 0;
      let heavyLightDecomposition = {};

      // Iterate over the nodes in the graph
      for (let node in graph) {
         // Find the root of the node in the heavy-light decomposition
         let root = findRoot(node);

         // Calculate the result for the node
         result += calculateNodeResult(graph, node, root);

         // Merge the node with its parent in the heavy-light decomposition
         mergeNodes(node, graph[node]);
      }

      return result;
   }

   // Function to calculate the result for a node in the graph
   function calculateNodeResult(graph, node, root) {
      // Initialize variables to store the result and the heavy-light decomposition
      let result = 0;
      let heavyLightDecomposition = {};

      // Iterate over the neighbors of the node
      for (let neighbor in graph[node]) {
         // Calculate the result for the neighbor
         result += calculateNodeResult(graph, neighbor, root);
      }

      // Return the result for the node
      return result;
   }

   // Apply the Heavy-Light Decomposition algorithm to the graph
   for (let node in graph) {
      heavyLightDecomposition[node] = node;
   }

   // Calculate the result using the heavy-light decomposition
   result = calculateResult();

   return result;
}

Asked in Top Tech Interviews

RazorpayZomato

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.