分析

一个非常自然的想法就是
枚举每个节点作为对称二叉树的根
然后左右遍历检查是否合格
最后取一个max

那么这个时间复杂度是多少呢
首先我们知道,若以为根节点
那么只有当左右子树大小相等时可以向下遍历
那么我们进而想,什么情况下
会有最多的可以遍历的根呢
当然就是完全二叉树的时候
因为一个点会被遍历,当且仅当根为其祖先
那么完全二叉树时,总共有个祖先
所以总的时间复杂度为:

代码

由于这道题是很久以前做的,码风比较清奇

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#include<cstring>
#include<string>
#define INF 0x7fffffff
#define LL long long
using namespace std;

const int MAXn=1e6+1;
LL Tree[MAXn][3],total;
LL sum[MAXn],val[MAXn];
LL x,y;
bool pd;

inline LL read() 
{
    char c=getchar();
    LL x=0,f=1;
    while(c<'0' || c>'9') {if(c=='-')f=-1;c=getchar();}
    while(c>='0' && c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}

void Symmetric_tree(LL aa,LL bb)
{
    if(aa==-1 && bb==-1) return;
    if(aa==-1 || bb==-1 || val[aa]!=val[bb]){pd=false; return;}
    Symmetric_tree(Tree[aa][1],Tree[bb][2]);
    Symmetric_tree(Tree[aa][2],Tree[bb][1]);
} 

LL Count(LL p)
{
    LL num=0;
    if(Tree[p][1]!=-1) num+=Count(Tree[p][1]);
    if(Tree[p][2]!=-1) num+=Count(Tree[p][2]);
    return num+1;
}

int main()
{
    total=read();    
    for(int i=1;i<=total;i++) val[i]=read();
    for(int i=1;i<=total;i++)
    {
        Tree[i][0]=i;
        x=read();y=read();
        Tree[i][1]=x;Tree[i][2]=y;
    }
    LL ans=1;
    for(int i=1;i<=total;i++)
    {
        pd=true;
        if(Tree[i][1]!=-1 && Tree[i][2]!=-1 && val[Tree[i][1]]==val[Tree[i][2]])
        {
            Symmetric_tree(Tree[i][1],Tree[i][2]);
            if(pd) ans=max(ans,Count(i));
        }
    }
    printf("%lld",ans);
    return 0;
}