


构建




// 关键点// int id[N], key[N], value[N];// int ch[N][2], parent[N], stk[N];// int tt;#include <bits/stdc++.h>using namespace std;const int N = 50010;int id[N], key[N], value[N];int ch[N][2], parent[N], stk[N];int tt;int n;bool cmp(int i, int j){ return key[i] < key[j];}int main(){ cin >> n; for (int i = 1; i <= n; i++){ cin >> key[i] >> value[i]; id[i] = i; } sort(id + 1, id + 1 + n, cmp); for (int s = 1; s <= n; s++){ int i = id[s]; int j, p = 0; // p表示刚刚退出栈的, 题意无儿子用0代替 while (tt > 0 && value[stk[tt]] > value[i]){ j = stk[tt--]; // 刚刚退出栈的是谁 ch[j][1] = p; // 刚刚退栈的右儿子赋值成上一个退掉的p parent[p] = j; // 上一个退栈的父亲是j p = j; // p更新,进行下一轮 } ch[i][0] = p; // 左儿子等于上一个退栈的p parent[p] = i; stk[++tt] = i; // i加入栈里 } // 最后清空一下栈的里东西 int j, p = 0; while (tt > 0){ j = stk[tt--]; ch[j][1] = p; parent[p] = j; p = j; } // 笛卡尔树的构造方式,决定了肯定有解 cout << "YES" << '\n'; for (int i = 1; i <= n; i++) cout << parent[i] << ' ' << ch[i][0] << ' ' << ch[i][1] << '\n'; return 0;}