P5018 [NOIP2018 普及组] 对称二叉树

先递归判断当前子树是不是对称二叉树,如果是就取 (max) 然后退出,否则继续递归寻找。

设判断 (k) 次后发现不对称则

[T(n)=T(k+a)+T(n-k-a)+k(ageq 0) ]

如果发现对称则

[T(n)=n ]

不难发现这是 (O(nlog n)) 的。

code:

#include<bits/stdc++.h>
using namespace std;
#define N 1000005
#define Max(x,y)((x)>(y)?x:y)
#define For(i,x,y)for(i=x;i<=(y);i++)
int l[N],r[N],v[N],s;
int read()
{
	int A;
	bool K;
	char C;
	C=A=K=0;
	while(C<'0'||C>'9')K|=C=='-',C=getchar();
	while(C>'/'&&C<':')A=(A<<3)+(A<<1)+(C^48),C=getchar();
	return(K?-A:A);
}
int sum(int i)
{
	if(!~i)return 0;
	return 1+sum(l[i])+sum(r[i]);
}
bool pd(int i,int j)
{
	if(!~i&&!~j)return 1;
	if(!~i||!~j||v[i]!=v[j])return 0;
	if(pd(l[i],r[j])&&pd(r[i],l[j]))return 1;
	return 0;
}
void dfs(int k)
{
	if(pd(l[k],r[k]))s=Max(sum(k),s);
	else
	{
		if(~l[k])dfs(l[k]);
		if(~r[k])dfs(r[k]);
	}
}
int main()
{
	int n,i;
	n=read();
	For(i,1,n)v[i]=read();
	For(i,1,n)l[i]=read(),r[i]=read();
	dfs(1);
	cout<<s;
	return 0;
}
原文地址:https://www.cnblogs.com/May-2nd/p/14855435.html