Here is the solution:
function preprocess()
dfs_init(1, -1, 0)
dfs_hld(1, -1, 0)
for v from 1 to n
seg_update(pos[v], val[v])
function update(v, x)
val[v] := x
seg_update(pos[v], x)
function query(u, v)
return path_query(u, v)
This runs in time and uses space.