image.png
image.png
image.png
image.png

构建

image.png
image.png
image.png
image.png

例题,POJ - 2201 Cartesian Tree

  1. // 关键点
  2. // int id[N], key[N], value[N];
  3. // int ch[N][2], parent[N], stk[N];
  4. // int tt;
  5. #include <bits/stdc++.h>
  6. using namespace std;
  7. const int N = 50010;
  8. int id[N], key[N], value[N];
  9. int ch[N][2], parent[N], stk[N];
  10. int tt;
  11. int n;
  12. bool cmp(int i, int j){
  13. return key[i] < key[j];
  14. }
  15. int main(){
  16. cin >> n;
  17. for (int i = 1; i <= n; i++){
  18. cin >> key[i] >> value[i];
  19. id[i] = i;
  20. }
  21. sort(id + 1, id + 1 + n, cmp);
  22. for (int s = 1; s <= n; s++){
  23. int i = id[s];
  24. int j, p = 0; // p表示刚刚退出栈的, 题意无儿子用0代替
  25. while (tt > 0 && value[stk[tt]] > value[i]){
  26. j = stk[tt--]; // 刚刚退出栈的是谁
  27. ch[j][1] = p; // 刚刚退栈的右儿子赋值成上一个退掉的p
  28. parent[p] = j; // 上一个退栈的父亲是j
  29. p = j; // p更新,进行下一轮
  30. }
  31. ch[i][0] = p; // 左儿子等于上一个退栈的p
  32. parent[p] = i;
  33. stk[++tt] = i; // i加入栈里
  34. }
  35. // 最后清空一下栈的里东西
  36. int j, p = 0;
  37. while (tt > 0){
  38. j = stk[tt--];
  39. ch[j][1] = p;
  40. parent[p] = j;
  41. p = j;
  42. }
  43. // 笛卡尔树的构造方式,决定了肯定有解
  44. cout << "YES" << '\n';
  45. for (int i = 1; i <= n; i++)
  46. cout << parent[i] << ' ' << ch[i][0] << ' ' << ch[i][1] << '\n';
  47. return 0;
  48. }