题目传送门
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const int maxn = 1000015;
const ULL mod = 1009; // 哈希の取模
inline int read() { // 快读
int s = 0, f = 1;
char ch = getchar();
while (ch < 48 || ch > 57) {
if (ch == 45) {
f = -1;
}
ch = getchar();
}
while (ch > 47 && ch < 58) {
s = (s << 3) + (s << 1) + ch - 48;
ch = getchar();
}
return s * f;
}
int n, ans, v[maxn], sz[maxn], child[maxn][2]; // sz[u]维护u及其子树的大小
ULL h[maxn][2], mod_pow[maxn]; // h[u][0]与h[u][1]分别维护u及其子树哈希值的正序和逆序,mod_pow[i]维护mod的i次幂(取模)
void dfs(int u) {
if (child[u][0] == -1 && child[u][1] == -1) { // 当u是叶子结点
h[u][0] = h[u][1] = v[u];
ans = max(ans, sz[u] = 1); // 更新ans
}
else if (child[u][0] == -1 && child[u][1] > 0) { // 当u只有左子树或右子树
dfs(child[u][1]);
sz[u] = sz[child[u][1]] + 1;
h[u][0] = v[u] * mod_pow[sz[child[u][1]]] + h[child[u][1]][0];
h[u][1] = h[child[u][1]][1] * mod + v[u];
}
else if (child[u][0] > 0 && child[u][1] == -1) {
dfs(child[u][0]);
sz[u] = sz[child[u][0]] + 1;
h[u][0] = h[child[u][0]][0] * mod + v[u];
h[u][1] = v[u] * mod_pow[sz[child[u][0]]] + h[child[u][0]][1];
}
else { // 当u同时有左子树和右子树
dfs(child[u][0]);
dfs(child[u][1]);
sz[u] = sz[child[u][0]] + sz[child[u][1]] + 1;
h[u][0] = h[child[u][0]][0] * mod_pow[sz[child[u][1]] + 1] + mod_pow[sz[child[u][1]]] * v[u] + h[child[u][1]][0];
h[u][1] = h[child[u][1]][1] * mod_pow[sz[child[u][0]] + 1] + mod_pow[sz[child[u][0]]] * v[u] + h[child[u][0]][1];
if (h[child[u][0]][0] == h[child[u][1]][1]) { // 更新ans
ans = max(ans, sz[u]);
}
}
return;
}
int main(void) {
mod_pow[0] = 1;
n = read();
for (register int i = 1; i <= n; i++) {
v[i] = read();
mod_pow[i] = mod_pow[i - 1] * mod; // 取模预处理
}
for (register int i = 1; i <= n; i++) {
child[i][0] = read();
child[i][1] = read();
}
dfs(1);
printf("%d", ans);
return 0;
}