You are given a tree rooted at node 0 that consists of n nodes numbered from
0 to n - 1. The tree is represented by an array parent of size n, where parent[i] is the parent of node i. Since node 0 is the root,
parent[0] == -1.
You are also given a string s of length n, where s[i] is the character assigned to node i.
We make the following changes on the tree one time simultaneously for all nodes x from 1 to n - 1:
Find the closest node y to node x such that y is an ancestor of x, and s[x] == s[y].
If node y does not exist, do nothing.
Otherwise, remove the edge between x and its current parent and make node y the new parent of x by adding an edge between them.
Return an array answer of size n where answer[i] is the size of the subtree rooted at node i in the final tree.
Input: parent =[-1,0,0,1,1,1], s ="abaabc"Output: [6,3,1,1,1,1]Explanation:

The parent of node 3 will change from node 1 to node 0.
Input: parent =[-1,0,4,0,1], s ="abbba"Output: [5,2,1,1,1]Explanation:

The following changes will happen at the same time:* The parent of node 4 will change from node 1 to node 0.* The parent of node 2 will change from node 4 to node 1.
We need to simulate the parent change for each node based on the closest ancestor with the same character. By using DFS and a stack for each character, we can efficiently find the correct ancestor for each node. After updating the parent relationships, we can compute the subtree sizes with another DFS.
classSolution {
funfindSubtreeSizes(parent: IntArray, s: String): IntArray {
val n = parent.size
val tree = Array(n) { mutableListOf<Int>() }
for (i in1 until n) tree[parent[i]].add(i)
val newParent = parent.copyOf()
val charStack = Array(26) { ArrayDeque<Int>() }
fundfs(u: Int) {
val c = s[u] - 'a'val prev = charStack[c].lastOrNull()
charStack[c].addLast(u)
if (u !=0&& prev !=null) newParent[u] = prev
for (v in tree[u]) dfs(v)
charStack[c].removeLast()
}
dfs(0)
val newTree = Array(n) { mutableListOf<Int>() }
for (i in1 until n) newTree[newParent[i]].add(i)
val ans = IntArray(n) { 1 }
fundfs2(u: Int) {
for (v in newTree[u]) {
dfs2(v)
ans[u] += ans[v]
}
}
dfs2(0)
return ans
}
}
classSolution:
deffindSubtreeSizes(self, parent: list[int], s: str) -> list[int]:
n = len(parent)
tree = [[] for _ in range(n)]
for i in range(1, n):
tree[parent[i]].append(i)
new_parent = parent[:]
char_stack = [[] for _ in range(26)]
defdfs(u: int):
c = ord(s[u]) - ord('a')
prev = char_stack[c][-1] if char_stack[c] else-1 char_stack[c].append(u)
if u !=0and prev !=-1:
new_parent[u] = prev
for v in tree[u]:
dfs(v)
char_stack[c].pop()
dfs(0)
new_tree = [[] for _ in range(n)]
for i in range(1, n):
new_tree[new_parent[i]].append(i)
ans = [1] * n
defdfs2(u: int):
for v in new_tree[u]:
dfs2(v)
ans[u] += ans[v]
dfs2(0)
return ans