#include
inline int max(int x, int y)
{
return x > y ? x : y;
}
const int MAXN = 1000000;
int cnt[MAXN + 5], lef[MAXN + 5], rig[MAXN + 5], ans;
int v[MAXN + 5]; // 节点的权值
// 检查左右子树是否对称
bool checkSym(int leftId, int rightId)
{
if(leftId == -1 && rightId == -1)
{
// 若左右子节点都不存在,则认为是对称
return true;
}
if(v[leftId] != v[rightId])
{
// 左子节点值 不等于 右子节点值,说明不对称
return false;
}
else
{
// 左子节点值等于右子节点值,则左左=右右且右左=左右,说明对称;否则不对称。注意要递归下去
return checkSym(lef[leftId], rig[rightId]) &&
checkSym(rig[leftId], lef[rightId]);
}
}
// 求第nodeId个节点为根节点的二叉树,所包含的节点总数
int nodeCnt(int nodeId)
{
// 当前节点不存在
if(-1 == nodeId)
{
return 0;
}
else
{
// 左子树节点数 + 右子树节点树 + root本身的节点数1
return cnt[nodeId] = nodeCnt(lef[nodeId]) +
nodeCnt(rig[nodeId]) + 1;
}
}
void dfs(int nodeId)
{
// 空节点为递归终止的条件
if(-1 == nodeId)
{
return;
}
// 左子树节点总数 等于 右子树节点总数,这是对称的前提
if(cnt[lef[nodeId]] == cnt[rig[nodeId]])
{
if(checkSym(lef[nodeId], rig[nodeId]))
{
// 若对称,获取总的节点数,并与原先的ans比较
ans = max(ans, cnt[nodeId]);
}
}
// 左子树下是否包含对称二叉树
dfs(lef[nodeId]);
// 右路子树是否包含对称二叉树
dfs(rig[nodeId]);
}
int main()
{
freopen("tree.in", "r", stdin);
freopen("tree.out", "w", stdout);
int n;
scanf("%d", &n);
for(int i=1; i<=n; i++)
{
scanf("%d", &v[i]);
}
for(int i=1; i<=n; i++)
{
scanf("%d%d", &lef[i], &rig[i]);
}
nodeCnt(1);
dfs(1);
printf("%dn", ans);
return 0;
}