时间限制:0.25s

空间限制:6M

题意:

给出n(n< 50000)个含双关键字(key,val)的节点,构造一颗树使该树,按key值是一颗二分查找树,按val值是一个小根堆.


Solution :

先按k值从小到大排序.

再从序列中找到最小的val值,将其作为根.再对它的左边和右边做同样的操作.左边最大的数做左儿子,右边做右儿子。递归即可.

这里要快速找到一个序列区间的最大值,用ST方法求RMQ就行了.

时间复杂度O(nlogN),空间复杂度O(n)

code:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <functional>
  5. #include <vector>
  6. #include <utility>
  7. using namespace std;
  8.  
  9. struct node {
  10. int key, val, ID;
  11. } p;
  12.  
  13. struct answer {
  14. int fa, lson, rson;
  15. } ans[51000];
  16.  
  17. typedef pair<int , int > P;
  18. vector<node> f;
  19. P st[51000][20];
  20. int n, x, y;
  21.  
  22. bool cmp (node a, node b) {
  23. return a.key < b.key;
  24. }
  25. //ST RMQ
  26. void ST() {
  27. for (int i = n - 1; i >= 0 ; i--)
  28. for (int j = 1; i + (1 << j) <= n; j++)
  29. {
  30. if (st[i][j - 1].first < st[i + (1 << j - 1)][j - 1].first)
  31. st[i][j] = st[i][j - 1];
  32. else
  33. st[i][j] = st[i + (1 << j - 1)][j - 1];
  34. }
  35. }
  36. //得到区间最小值的位置
  37. int getmin (int l, int r)
  38. {
  39. P tem;
  40. tem=st[l][0];
  41. for (int k = 0; l + (1 << k) <= r; k++)
  42. {
  43. if (st[l][k].first < tem.first)
  44. tem = st[l][k];
  45. if (st[r - (1 << k) + 1][k].first < tem.first)
  46. tem = st[r - (1 << k) + 1][k];
  47. }
  48. return tem.second;
  49. }
  50. //递归建树
  51. int make (int l, int r, int fa)
  52. {
  53. int k = getmin (l, r);
  54. int pos = f[k].ID;
  55. ans[pos].fa = fa;
  56. if (l >= r) return pos;
  57. if (l < k) ans[pos].lson = make (l, k - 1, pos);
  58. if (k < r) ans[pos].rson = make (k + 1, r, pos);
  59. return pos;
  60. }
  61.  
  62. int main()
  63. {
  64. scanf("%d",&n);
  65. for (int i = 0; i < n; i++)
  66. {
  67. scanf("%d %d",&x,&y);
  68. p.key = x, p.val = y, p.ID = i + 1;
  69. f.push_back (p);
  70. }
  71. //按key值从小到大排序
  72. sort (f.begin(), f.end(), cmp);
  73. for (int i = 0; i < (int) f.size(); i++)
  74. st[i][0] = make_pair (f[i].val, i);
  75. ST();
  76. make (0, n - 1, 0);
  77. //一定有解直接输出 "YES"
  78. puts("YES\n");
  79. for (int i = 1; i <= n; i++)
  80. printf("%d %d %d\n",ans[i].fa,ans[i].lson,ans[i].rson);
  81. return 0;
  82. }

  

  

SGU 155.Cartesian Tree的更多相关文章

  1. [sgu P155] Cartesian Tree

    155. Cartesian Tree time limit per test: 0.25 sec. memory limit per test: 65536 KB input: standard i ...

  2. Algorithm: cartesian tree

    http://baike.baidu.com/link?url=XUt5fXQ-jtFBM0UdKiGA41_NWFvdFSYwVsy4SVvCRRuEBvNkLfT9TgOtzsXvaOT9nuq_ ...

  3. 笛卡尔树Cartesian Tree

    前言 最近做题目,已经不止一次用到笛卡尔树了.这种数据结构极为优秀,但是构造的细节很容易出错.因此写一篇文章做一个总结. 笛卡尔树 Cartesian Tree 引入问题 有N条的长条状的矩形,宽度都 ...

  4. PAT-2019年冬季考试-甲级 7-4 Cartesian Tree (30分)(最小堆的中序遍历求层序遍历,递归建树bfs层序)

    7-4 Cartesian Tree (30分)   A Cartesian tree is a binary tree constructed from a sequence of distinct ...

  5. Day6 - J - Cartesian Tree POJ - 2201

    Let us consider a special type of a binary search tree, called a cartesian tree. Recall that a binar ...

  6. PAT-1167(Cartesian Tree)根据中序遍历序列重建最小堆

    Cartesian Tree PAT-1167 一开始我使用数组进行存储,但是这样可能会导致无法开足够大的数组,因为树如果是链表状的则无法开这么大的数组(虽然结点很少). 正确的解法还是需要建树,使用 ...

  7. POJ 2201 Cartesian Tree ——笛卡尔树

    [题目分析] 构造一颗笛卡尔树,然后输出这棵树即可. 首先进行排序,然后用一个栈维护最右的树的节点信息,插入的时候按照第二关键字去找,找到之后插入,下面的树成为它的左子树即可. 然后插入分三种情况讨论 ...

  8. OpenJudge Cartesian Tree

    [代码] #include <cstdio> #include <cstdlib> #include <cstring> #include <algorith ...

  9. CF1290E Cartesian Tree

    考虑笛卡尔树的意义: 一个点在笛卡尔树中的子树,代表以他为最小/最大值的区间. 所以一个点的子树大小,一定是类似到达序列边界或者被一个比他更大的数隔离. 考虑记录 \(l_i,r_i\) 为第 \(i ...

随机推荐

  1. 传智播客C语言视频第二季(第一季基础上增加诸多C语言案例讲解,有效下载期为10.5-10.10关闭)

    卷 backup 的文件夹 PATH 列表卷序列号为 00000025 D4A8:14B0J:.│  1.txt│  c语言经典案例效果图示.doc│  ├─1传智播客_尹成_C语言从菜鸟到高手_第一 ...

  2. 利用NSIS软件制作C#安装包

    最近在做C#程序安装包,结果网上看到这个软件还是不错的,可以尝试以下. NSIS 是“Nullsoft 脚本安装系统”(Nullsoft Scriptable Installation System) ...

  3. VGA IP核的制作

    今天看了本<系统晶片设计-使用NIOS>这本书,看到VGA IP核的设计不错,特移植到Cyclone III上来,试验一下效果. 顶层代码:binary_VGA.v module bina ...

  4. lightoj 1030 概率dp

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1030 #include<cstdio> #include<cstri ...

  5. Nearly prime numbers - SGU 113(素数)

    题目大意:判断一个数是否是两个素数的乘积,如果是,输出Yes,否则No. 分析:先打表求出来一部分素因子,用素数对素数判定还是比较快的. 代码如下: ========================= ...

  6. hdoj 2647 Reward【反向拓扑排序】

    Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  7. java 新手

    public class hello{ public static void main(String args[]){ int a=23,b=32,c=34; int s=Math.max(a,c); ...

  8. 用函数生成select选择框

    // 生成 html select option 标签 function build_options($options, $opt='',$k='') { $frags = array(); if ( ...

  9. OBJ解析

    OBJ文件是Alias|Wavefront公司为它的一套基于工作站的3D建模和动画软件"Advanced Visualizer"开发的一种标准3D模型文件格式,很适合用于3D软件模 ...

  10. mac下修改mysql的默认字符集为utf8

    1,检查默认安装的mysql的字符集 mysql> show variables like '%char%'; +--------------------------+------------- ...