There are n types of units indexed from 0 to n - 1.
You are given a 2D integer array conversions of length n - 1, where conversions[i] = [sourceUniti, targetUniti, conversionFactori]. This indicates that a single unit of type sourceUniti is equivalent to conversionFactori units of type targetUniti.
You are also given a 2D integer array queries of length q, where queries[i] = [unitAi, unitBi].
Return an array answer of length q where answer[i] is the number of units of type unitBi equivalent to 1 unit of type unitAi, and can be represented as p/q where p and q are coprime. Return each answer[i] as pq-1modulo109 + 7, where q-1 represents the multiplicative inverse of q modulo 109 + 7.
In the first query, we can convert unit 1 into 3 units of type 2 using the inverse of conversions[0], then conversions[1].
In the second query, we can convert unit 1 into 1/2 units of type 0 using the inverse of conversions[0]. We return 500000004 since it is the multiplicative inverse of 2.
In the first query, we can convert unit 1 into 3 units of type 2 using the inverse of conversions[0], then conversions[1].
In the second query, we can convert unit 0 into 12 units of type 4 using conversions[1], then conversions[3].
In the third query, we can convert unit 6 into 1 unit of type 5 using the inverse of conversions[5], the inverse of conversions[2], conversions[1], then conversions[4].
In the fourth query, we can convert unit 4 into 2 units of type 6 using the inverse of conversions[3], the inverse of conversions[1], conversions[2], then conversions[5].
In the fifth query, we can convert unit 6 into 1/12 units of type 1 using the inverse of conversions[5], the inverse of conversions[2], then conversions[0]. We return 83333334 since it is the multiplicative inverse of 12.
Constraints:
2 <= n <= 105
conversions.length == n - 1
0 <= sourceUniti, targetUniti < n
1 <= conversionFactori <= 109
1 <= q <= 105
queries.length == q
0 <= unitAi, unitBi < n
It is guaranteed that unit 0 can be uniquely converted into any other unit through a combination of forward or backward conversions.
Solutions
Solution 1: DFS + Modular Inverse
Thinking
The conversion tree is the same as before, so \(\textit{res}[i]\) β how many units of \(i\) equal one unit of \(0\) β is already known. Queries ask for a ratio between two units.
The factor from \(\textit{unitA}\) to \(\textit{unitB}\) is \(\textit{res}[B] \cdot \textit{res}[A]^{-1}\). The modulus is prime, so the inverse is \(a^{MOD-2}\).
The conversion relations form a directed tree rooted at \(0\). Starting a DFS from node \(0\), we maintain res[i] as the number of units of type \(i\) that equal \(1\) unit of type \(0\).
For a query \((unitA, unitB)\), the answer is \(\frac{res[unitB]}{res[unitA]}\), which modulo \(10^9 + 7\) equals res[unitB] * res[unitA]^(MOD - 2) % MOD, where MOD - 2 is used to compute the modular inverse via Fermat's little theorem.
The time complexity is \(O(n + q \log MOD)\) and the space complexity is \(O(n)\), where \(n\) is the number of unit types and \(q\) is the number of queries.
There are \(n - 1\) conversions and a unique path from \(0\), so the graph is a directed tree rooted at \(0\). With \(n \le 10^5\), recursing from the root and multiplying along the way reaches depth \(n\) on a chain and overflows the call stack. Each unit's factor relative to \(0\) depends only on that path.
An explicit stack of \((unit, accumulated\ factor)\) therefore starts at \((0, 1)\). Popping a frame writes \(\textit{res}[i]\), and each successor is pushed with the current factor multiplied by the edge weight, modulo \(10^9 + 7\).
A query asks for a ratio between two units. The factor from \(\textit{unitA}\) to \(\textit{unitB}\) is \(\textit{res}[B] \cdot \textit{res}[A]^{-1}\). The modulus is prime, so the inverse is \(a^{MOD-2}\).
The conversion relations form a directed tree rooted at \(0\). An explicit stack walks from the root. Each frame is \((unit, accumulated\ factor)\), starting from \((0, 1)\). Popping a frame writes res[i], the number of units of type \(i\) that equal \(1\) unit of type \(0\). Each successor is pushed with the current factor multiplied by the edge weight, modulo \(10^9 + 7\).
For a query \((unitA, unitB)\), the answer is \(\frac{res[unitB]}{res[unitA]}\), which modulo \(10^9 + 7\) equals res[unitB] * res[unitA]^(MOD - 2) % MOD, where MOD - 2 is used to compute the modular inverse via Fermat's little theorem.
The time complexity is \(O(n + q \log MOD)\) and the space complexity is \(O(n)\), where \(n\) is the number of unit types and \(q\) is the number of queries.