You are given an unweighted tree with N nodes and each node starts with value 0. There will be Q queries. The 1st type of query will change the value at a node to a new value. The 2nd type of query asks for the sum of values of nodes on the simple path between two given nodes.
The value of any node is always between 0 and 10^9 and N, Q are between 1 and 10^5. Offline query answering is allowed.
I tried with storing all node values in array and running dfs to find path sum, but it exceeds 1s time limit.
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
const int MAX_INPUT = 1e5 + 5;
vector<int> graph[MAX_INPUT];
int values[MAX_INPUT];
bool seen[MAX_INPUT];
long long getSum(int from, int to) {
if (seen[from]) {
return -1;
}
seen[from] = true;
if (from == to) {
return values[from];
}
for (int n : graph[from]) {
int nsum = getSum(n, to);
if (nsum >= 0) {
return values[from] + nsum;
}
}
return -1;
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int N;
cin >> N;
for (int i = 0; i < N - 1; i++) {
int a, b;
cin >> a >> b;
graph[a].push_back(b);
graph[b].push_back(a);
}
int Q;
cin >> Q;
for (int q = 0; q < Q; q++) {
int type;
cin >> type;
if (type == 1) {
int node, newvalue;
cin >> node >> newvalue;
values[node] = newvalue;
} else {
int node1, node2;
cin >> node1 >> node2;
memset(seen, 0, N + 1);
long long pathsum = getSum(node1, node2);
cout << pathsum << '\n';
}
}
}
The input format is:
- first line is N (number of nodes)
- next N - 1 lines contain two node numbers that gives an edge in the tree (node numbers are integers between 1 and N)
- next line is Q (number of queries)
- next Q lines each have 3 integers t, a, b
- if t is 1, it is type 1 query to set value at node a to b
- if t is 2, it is type 2 query to ask sum of values of nodes on the simple path between a and b
- you never get invalid input
An example input is
5
1 2
1 5
2 3
2 4
5
1 2 10
2 3 4
1 1 5
2 2 5
2 4 3
and output
10
15
10
What is a more efficient way to solve these queries?