/*
Problem: Sum of Jealousy Values in a Rooted Tree
Company Tag: Rubrik OA
Problem Statement:
We are given an undirected tree with n nodes labeled from 1 to n.
The tree is rooted at node 1.
For each node u:
jealousy value of u = number of nodes v in subtree(u) such that v > u
Return the sum of jealousy values of all nodes modulo 1e9 + 7.
Constraints:
2 <= n <= 100000
A.length == B.length == n - 1
1 <= A[i], B[i] <= n
Input forms a valid tree.
Brute Force:
For every node, traverse its subtree and count labels greater than it.
Why Brute Force Fails:
For every node, subtree traversal can take O(n).
For all nodes, it becomes O(n^2).
Optimized Idea:
Use Euler Tour.
After rooting the tree:
subtree(u) becomes a continuous range:
[tin[u], tout[u]]
Process labels from n down to 1.
When processing label u:
All labels greater than u are already inserted in Fenwick Tree.
Explanation Block:
Fenwick Tree stores which nodes with greater labels have been seen.
For current node u:
Query Fenwick Tree in range [tin[u], tout[u]]
That gives:
number of greater labels inside subtree(u)
Then insert u into Fenwick Tree for future smaller labels.
Dry Run:
Tree:
1 - 2
2 - 3
1 - 4
Node 1 subtree has 2, 3, 4:
contribution = 3
Node 2 subtree has 3:
contribution = 1
Node 3 and 4:
contribution = 0
Total = 4
Time Complexity:
O(n log n)
Space Complexity:
O(n)
*/
#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007LL;
class Fenwick {
public:
int n;
vector<int> bit;
Fenwick(int n) {
this->n = n;
bit.assign(n + 1, 0);
}
void add(int index, int value) {
while (index <= n) {
bit[index] += value;
index += index & -index;
}
}
int sum(int index) {
int result = 0;
while (index > 0) {
result += bit[index];
index -= index & -index;
}
return result;
}
int rangeSum(int left, int right) {
return sum(right) - sum(left - 1);
}
};
long long sumOfJealousyValues(int n, vector<int>& A, vector<int>& B) {
vector<vector<int>> graph(n + 1);
for (int i = 0; i < n - 1; i++) {
graph[A[i]].push_back(B[i]);
graph[B[i]].push_back(A[i]);
}
vector<int> parent(n + 1, -1);
vector<int> tin(n + 1);
vector<int> tout(n + 1);
vector<int> idx(n + 1, 0);
int timer = 0;
vector<int> st;
// Iterative DFS to avoid recursion depth issues.
st.push_back(1);
parent[1] = 0;
while (!st.empty()) {
int u = st.back();
// First time visiting node u.
if (idx[u] == 0) {
tin[u] = ++timer;
}
if (idx[u] < (int)graph[u].size()) {
int v = graph[u][idx[u]];
idx[u]++;
if (v == parent[u]) {
continue;
}
parent[v] = u;
st.push_back(v);
} else {
// All children are processed, so subtree of u ends here.
tout[u] = timer;
st.pop_back();
}
}
Fenwick fw(n);
long long ans = 0;
// Process labels from larger to smaller.
for (int label = n; label >= 1; label--) {
int u = label;
// Fenwick currently contains nodes having labels greater than u.
int greaterInsideSubtree = fw.rangeSum(tin[u], tout[u]);
ans = (ans + greaterInsideSubtree) % MOD;
// Insert current node for future smaller labels.
fw.add(tin[u], 1);
}
return ans;
}
int main() {
int n = 4;
vector<int> A = {1, 2, 1};
vector<int> B = {2, 3, 4};
cout << sumOfJealousyValues(n, A, B) << endl;
return 0;
}