裸笛卡尔建树。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int key,value,id;
bool operator < (const node &cmp)const
{
return key<cmp.key;
}
}save[55555];
int tab[55555];
int pre[55555],lson[55555],rson[55555];
int top=-1;
int n;
void init()
{
memset(tab,-1,sizeof tab);
top=-1;
for(int i=1;i<=n;i++)pre[i]=lson[i]=rson[i]=0;
}
void build_cartesian_tree()
{
for(int i=1;i<=n;i++)
{
int k=top;
while(k>=0 && save[tab[k]].value>save[i].value)k--;//知道第一个value 比当前节点小的
if(k!=-1)//如果这个不是最小的
{
pre[save[i].id]=save[tab[k]].id;
rson[save[tab[k]].id]=save[i].id;
}
if(k<top)
{//如果这个是最大的
pre[save[tab[k+1]].id]=save[i].id;
lson[save[i].id]=save[tab[k+1]].id;
}
tab[++k]=i;//把value比当前节点大的节点全部从栈里删除掉
top=k;//因为value大的都在当前节点的下面了,放在下面和放在当前节点这里是一样的
}
pre[save[tab[0]].id]=0;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=1;i<=n;i++)
{
scanf("%d%d",&save[i].key,&save[i].value);
save[i].id=i;
}
sort(save+1,save+1+n);//按key排序
build_cartesian_tree();
printf("YES\n");
for(int i=1;i<=n;i++)
printf("%d %d %d\n",pre[i],lson[i],rson[i]);
}
return 0;
}