构建排序二叉树只需根据先序遍历顺序插入即可,判断红黑树的每个祖先到叶子节点的黑点数相同,只需判断根节点到叶子节点的黑点数即可,因为如果根节点到叶子节点黑点数相同的话,那么对于任意祖先,祖先到根节点路径唯一,那么黑点数唯一,减去之后的黑点数还是相同的。
#include<cstdio>
#include<cmath>
using namespace std;
const int N=30+5;
int ch[N][2],key[N],dfn,rt,flag,ss;
void insert(int x)
{
key[++dfn]=x,ch[dfn][0]=ch[dfn][1]=0;
if(!rt){rt=dfn;return;}
int now=rt,pre=rt;
while(now)
{
pre=now;
if(abs(key[now])>abs(x)) now=ch[now][0];
else now=ch[now][1];
}
if(abs(key[pre])>abs(x)) ch[pre][0]=dfn;
else ch[pre][1]=dfn;
}
void dfs(int u,int black)
{
if(u==0)
{
if(ss==-1) ss=black;
else if(ss!=black) flag=0;
return;
}
int sum=0;
if(key[u]>0) sum++;
else if(key[ch[u][0]]<0||key[ch[u][1]]<0) flag=0;
dfs(ch[u][0],sum+black);
dfs(ch[u][1],sum+black);
}
int check()
{
if(key[rt]<0) return 0;
flag=1;
dfs(rt,0);
if(!flag) return 0;
return 1;
}
int main()
{
int k;scanf("%d",&k);
while(k--)
{
dfn=rt=0,ss=-1;
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
insert(x);
}
if(check()) puts("Yes");
else puts("No");
}
return 0;
}