【题目分析】
构造一颗笛卡尔树,然后输出这棵树即可。
首先进行排序,然后用一个栈维护最右的树的节点信息,插入的时候按照第二关键字去找,找到之后插入,下面的树成为它的左子树即可。
然后插入分三种情况讨论(最下面,中间,成为了新的树根)
【代码】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
int k,a,id;
}a[50005],st[50005];
int ans[50005][3];
int cmp(node a,node b)
{return a.k<b.k;}
int n;
void solve()
{
node now;
int top=0,x,y,z;
st[top++]=a[1];
for (int i=2;i<=n;++i)
{
int flag=0;
while (top>0&&st[top-1].a>a[i].a)
{
flag=1;
now=st[--top];
}
if (!flag)
{
x=st[top-1].id;
y=a[i].id;
ans[x][2]=y;
ans[y][0]=x;
st[top++]=a[i];
}
else
{
if (top)
{
x=st[top-1].id;
y=a[i].id;
z=now.id;
ans[x][2]=y;
ans[y][0]=x;
ans[z][0]=y;
ans[y][1]=z;
st[top++]=a[i];
}
else
{
y=a[i].id;
z=now.id;
ans[y][1]=z;
ans[z][0]=y;
st[top++]=a[i];
}
}
}
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;++i)
{
scanf("%d%d",&a[i].k,&a[i].a);
a[i].id=i;
}
sort(a+1,a+n+1,cmp);
solve();
printf("YES\n");
for (int i=1;i<=n;++i) printf("%d %d %d\n",ans[i][0],ans[i][1],ans[i][2]);
}