笛卡尔树。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ID(x) node[x].id
using namespace std;
inline int read()
{
int x = 0, f = 1, t = getchar();
while(t < 48 || t > 57) t == 45 ? f = -1 : 0, t = getchar();
while(t >= 48 && t <= 57) x = (x<<1) + (x<<3) + t - 48, t = getchar();
return x * f;
}
const int maxn = 50005;
const int INF = 0x3f3f3f3f;
struct Node
{
int v, r, id;
bool operator < (const Node &rhs) const {
return v < rhs.v;
}
}node[maxn];
struct Ans
{
int fa, lc, rc;
}ans[maxn];
int n, s[maxn], top;
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
n = read();
for(int i = 1; i <= n; ++i)
{
int v = read(), r = read();
node[i] = (Node){v, r, i};
}
node[0].r = -INF;
sort(node + 1, node + n + 1);
s[++top] = 1;
for(int i = 2; i <= n; ++i)
{
while(top >= 0 && node[i].r < node[s[top]].r)
--top;
if(top)
{
Ans &a = ans[ID(i)], &aa = ans[ID(s[top])];
a.fa = ID(s[top]);
a.lc = aa.rc;
ans[aa.rc].fa = ID(i);
ans[ans[ID(s[top])].rc].fa = ID(i);
aa.rc = ID(i);
}
else
{
ans[ID(s[1])].fa = ID(i);
ans[ID(i)].lc = ID(s[1]);
}
s[++top] = i;
}
puts("YES");
for(int i = 1; i <= n; ++i)
printf("%d %d %d\n", ans[i].fa, ans[i].lc, ans[i].rc);
#ifndef ONLINE_JUDGE
fclose(stdin), fclose(stdout);
#endif
return 0;
}