poj 2201(RMQ+笛卡尔树)
来源:互联网 发布:知乎周刊一共多少期 编辑:程序博客网 时间:2024/05/29 12:12
给出一些结点
每个节点有两个关键字
要求构造一棵树
第一个关键字满足二叉搜索树的性质,第二个关键字满足小堆的性质
解题思路:这道题我开始是用第二关键字从小到大排序,然后从1-n去添加节点。这样是符合最小堆的性质,假设添加第i个节点,那么首先去找[1,i-1]这段区间的第一关键字的最小值和最大值,如果i节点的第一关键字大于最大值,就直接添加到最大值节点的右儿子,如果小于最小值,就添加到最小值节点的左儿子,否则就直接从根节点往下找。可是超时了,其实超时的原因还蛮明显的,因为你添加的i节点不一定每次都是大于最大值,小于最小值,更多的情况可能是在中间值,这样每次都要从根节点出发往下走,这样就会造成遍历的时间太多了。但按照这种思路,很难直接找到i节点的父节点是谁,因为[1,i-1]区间内的第一关键字是无序的。
参考了网上的思路,绝大部分都是按照第一关键字排序,然后再去找区间段内的最小值作为子树的根节点。
http://blog.csdn.net/sdj222555/article/details/7909198
我的TLE:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int maxn = 50005;struct Node{int k,a;int id;bool operator < (const Node &T){return a < T.a;}}tree[maxn];struct Result{int parent,left,right;}res[maxn];int n,value[maxn],dp_max[maxn][20],dp_min[maxn][20];int _max(int l,int r){if(tree[l].k > tree[r].k) return l;return r;}int _min(int l,int r){if(tree[l].k < tree[r].k) return l;return r;}void initRMQ(){for(int i = 1; i <= n; i++)dp_max[i][0] = dp_min[i][0] = i;for(int j = 1; (1 << j) <= n; j++)for(int i = 1; i + (1 << j) - 1 <= n; i++){dp_max[i][j] = _max(dp_max[i][j-1],dp_max[i+(1<<j-1)][j-1]);dp_min[i][j] = _min(dp_min[i][j-1],dp_min[i+(1<<j-1)][j-1]);}}int MaxValue(int l,int r){int k = (int)(log((r - l + 1)*1.0) / log(2.0));return _max(dp_max[l][k],dp_max[r-(1<<k)+1][k]);}int MinValue(int l,int r){int k = (int)(log((r - l + 1)*1.0) / log(2.0));return _min(dp_min[l][k],dp_min[r-(1<<k)+1][k]);}void Build(){int maxm,minm;for(int i = 1; i <= n; i++)res[i].parent = res[i].left = res[i].right = 0;for(int i = 2; i <= n; i++){maxm = MaxValue(1,i-1);minm = MinValue(1,i-1);if(tree[i].k > tree[maxm].k){res[tree[maxm].id].right = tree[i].id;res[tree[i].id].parent = tree[maxm].id;}else if(tree[i].k < tree[minm].k){res[tree[minm].id].left = tree[i].id;res[tree[i].id].parent = tree[minm].id;}else{int p = tree[1].id;while(true){if(tree[i].k > value[p]){if(res[p].right != 0)p = res[p].right;else{res[p].right = tree[i].id;res[tree[i].id].parent = p;break;}}else{if(res[p].left != 0)p = res[p].left;else{res[p].left = tree[i].id;res[tree[i].id].parent = p;break;}}}}}}int main(){while(scanf("%d",&n)!=EOF){for(int i = 1; i <= n; i++){scanf("%d%d",&tree[i].k,&tree[i].a);tree[i].id = i;value[i] = tree[i].k;}sort(tree+1,tree+1+n);initRMQ();Build();printf("YES\n");for(int i = 1; i <= n; i++)printf("%d %d %d\n",res[i].parent,res[i].left,res[i].right);}return 0;}
0 0
- POJ 2201 RMQ 笛卡尔树
- poj 2201(RMQ+笛卡尔树)
- poj 2201 笛卡尔树
- poj 2201 笛卡尔树
- poj 2201 笛卡尔树
- poj 1785 构造笛卡尔树(右链插入/RMQ)
- poj1785 笛卡尔树无rmq
- POJ-2201 Cartesian Tree【笛卡尔树】
- POJ 2201 Cartesian Tree 笛卡尔树
- POJ 2201 Cartesian Tree 【笛卡尔树】
- POJ 2201 Cartesian Tree (笛卡尔树)
- POJ-2201-Cartesian Tree(笛卡尔树)
- POJ 2201 Cartesian Tree 笛卡尔树
- POJ-2201 Cartesian Tree(笛卡尔树)
- poj 2201 Cartesian Tree 笛卡尔树
- POJ 1785 Binary Search Heap Construction 【笛卡尔树构造,线段树RMQ(Range Max/Min Query)】
- POJ 2201 Cartesian Tree 笛卡尔树裸题加讲解
- POJ 2823 线段树,RMQ
- 基于DCMTK和OpenCV的DR图像拼接
- 从服务器获取报表模板到html页面显示报表pdf
- struts2 - execAndWait(拦截器实例)
- ajax跨域获取数据解决方案---JSON
- VC++2005下的ADO SQL语句(like,count,distinct)和操作(转)
- poj 2201(RMQ+笛卡尔树)
- iOS模拟器和真机调试时App的安装文件路径问题
- 网页响应状态码
- leetcode 13. Roman to Integer
- grep和管道符
- Javascript面试题
- 10 Ways to Learn Java in just a Couple of Weeks
- oracle 修改字符集 修改为ZHS16GBK
- 2016SDAU编程练习一1009