POJ2182 -- 线段树
来源:互联网 发布:qq飞车改车吧 软件 编辑:程序博客网 时间:2024/04/30 04:32
一。线段树
线段树类似于区间树,它在每个节点之间保存一个区间:[a,b] , 那它左儿子保存的区间是:[a, (a+b)/2] ,右儿子保存的区间是:[(a+b)/2 +1 , b ]。
假设,父节点的标号为k, 那么左儿子的标号是2*k,右儿子的标号是2*k +1 .
假设,此时需要保存1-5的区间, 那么子节点的个数为5, 而线段树需要的空间约为3*5 =15个,即数组大小的3倍左右。
二。
POJ2182中构造的线段树为:(参加下图和代码)
typedef struct treeNode{ int left; int right; int number; //存放的是left和right这个区间,有几个数}treeNode;
treeNode nodeArr[3*MAX]; //静态数组,void buildSegTree(int node, int left, int right){ nodeArr[node].left = left ; nodeArr[node].right = right; nodeArr[node].number = right -left +1; // [1,5] 之间有5个数 if(left == right){ return; } buildSegTree(node<<1, left, (left+right)>>1); //node << 1 : node*2 ; (left+right)>>1: (left+right)/2; buildSegTree((node<<1) +1, ((left+right)>>1) +1 , right);}
在数节点treeNode中, 其中number值可以定义为自己所需要的值, 在这里是定义为这个区间有几头牛。
在构造树的时候,采用递归的方法,如果区间只有一个数,则返回,否则递归构造左右子树。
三。
该题的关键点在于,从最后一头牛开始,最后一头牛的编号为input[i]+1,且如果查找到该牛的编号,需要在它的树节点中,删除它的存在,即nodeArr[node].number--,也就是说区间1-3,原来有3头牛,查找到了编号为1的牛,那么区间1-3就还有2头牛;
还有一点需要注意的是,在查找右儿子的时候,查的是左起第number-nodeArr[2*node].number个数
查看全部代码:
#include <stdio.h>#include <stdlib.h>#define MAX 8001int N;int input[MAX];int output[MAX];typedef struct treeNode{ int left; int right; int number; //存放的是left和right这个区间,有几个数}treeNode;treeNode nodeArr[3*MAX]; //静态数组,void buildSegTree(int node, int left, int right){ nodeArr[node].left = left ; nodeArr[node].right = right; nodeArr[node].number = right -left +1; // [1,5] 之间有5个数 if(left == right){ return; } buildSegTree(node<<1, left, (left+right)>>1); //node << 1 : node*2 ; (left+right)>>1: (left+right)/2; buildSegTree((node<<1) +1, ((left+right)>>1) +1 , right);}int search(int node , int number){ nodeArr[node].number--; if(nodeArr[node].left == nodeArr[node].right){ return nodeArr[node].left; } if(nodeArr[2*node].number >= number){ //查左边 return search(2*node,number); } if(nodeArr[2*node].number < number){ //查右边 return search(2*node+1,number-nodeArr[2*node].number); //查右边的左起第number-nodeArr[2*node].number个数 }}int main(){ memset(input, 0 ,sizeof(input)); memset(output, 0 ,sizeof(output)); memset(nodeArr, 0 ,sizeof(nodeArr)); //freopen("input.txt","r",stdin); scanf("%d",&N); int i=2; for(i=2;i<=N;i++){ scanf("%d",&input[i]); } input[1]=0; buildSegTree(1,1,N); for(i=N;i>0;i--){ output[i] = search(1,input[i]+1); } for(i=1;i<=N;i++){ printf("%d\n",output[i]); } return 0;}
0 0
- poj2182 线段树
- POJ2182 -- 线段树
- Lost Cows poj2182 线段树
- poj2182 Lost Cows (线段树)
- Lost Cows(线段树 POJ2182)
- poj2182 Lost Cows(线段树)
- poj2182 线段树/线段数组+二分搜索
- poj2182(线段树计算元素位置)
- POJ2182 Lost Cows 线段树单点更新
- poj2182 lost cows题解(线段树)
- 见微知著----POJ2182(线段树简介)
- hdu 2711&&poj2182 Lost Cows (线段树)
- 线段树和树状数组各过一次POJ2182
- poj2182
- poj2182
- poj2182
- 线段树 查询删除 后序遍历 POJ2182 Lost Cows解题报告
- POJ2182 牛重新排序 树狀数组的应用
- PHP加密解密字符串汇总_php技巧_脚本之家
- grunt-rev 和grunt-usemin 的一些感悟
- 机器学习经典博客链接
- Android的内存,进程调度管理
- java:快速文件分割及合并
- POJ2182 -- 线段树
- 内存泄露
- redis 学习笔记(1)-编译、启动、停止
- 推荐 11 款 React Native 开源移动 UI 组件
- Javascrip的应用
- 黑马程序员__java基础__多线程
- iOS动画浅析
- 第十五周 课后实践:阅读程序2
- Java并发编程基础构建模块(02)——并发容器