poj 2104:K-th Number(划分树,经典题)
Time Limit: 20000MS | Memory Limit: 65536K | |
Total Submissions: 35653 | Accepted: 11382 | |
Case Time Limit: 2000MS |
Description
That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?"
For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.
Input
The second line contains n different integer numbers not exceeding 109 by their absolute values --- the array for which the answers should be given.
The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).
Output
Sample Input
- 7 3
- 1 5 2 6 3 7 4
- 2 5 3
- 4 4 1
- 1 7 3
Sample Output
- 5
- 6
- 3
Hint
Source
- #include <iostream>
- #include <stdio.h>
- #include <algorithm>
- using namespace std;
- #define MAXN 100005
- struct Divide_tree{ //划分树的结构(4个数组,2个操作)
- int arr[MAXN]; //原数组
- int sorted[MAXN]; //排序后数组
- int sum[][MAXN]; //记录第i层1~j划分到左子树的元素个数(包括j)
- int dat[][MAXN]; //记录第i层元素序列
- void build(int c,int L,int R) //建树,主要是建立sum[][]和dat[][]数组
- {
- int mid = (L+R)>>;
- int lsame = mid-L+; //lsame用来记录和中间值val_mid相等的,且可以分到左孩子的数的个数
- //简单来说就是可以放入左孩子的,与中间值val_mid相等的数的个数
- int lp=L,rp=mid+; //当前节点的左孩子和右孩子存数的起点
- for(int i=L;i<mid;i++) //获得一开始的lsame
- if(sorted[i]<sorted[mid])
- lsame--;
- for(int i=L;i<=R;i++){ //从前往后遍历一遍,
- //确定当前节点区间内的所有元素的归属(放在左孩子或者放在右孩子)
- if(i==L) sum[c][i]=;
- else sum[c][i]=sum[c][i-];
- if(dat[c][i]<sorted[mid]){ //当前元素比中间值val_mid小,放入左孩子
- dat[c+][lp++] = dat[c][i];
- sum[c][i]++;
- }
- else if(dat[c][i]>sorted[mid]) //当前元素比中间值val_mid大,放入右孩子
- dat[c+][rp++] = dat[c][i];
- else{ //当前元素值与中间值val_mid相等,根据lsame数判断放入左孩子还是右孩子
- if(lsame){
- lsame--;
- sum[c][i]++;
- dat[c+][lp++]=sorted[mid];
- }
- else{
- dat[c+][rp++]=sorted[mid];
- }
- }
- }
- if(L==R) return ; //递归出口,遇到叶子节点
- build(c+,L,mid); //递归进入左孩子区间
- build(c+,mid+,R); //递归进入右孩子区间
- }
- int query(int c,int L,int R,int ql,int qr,int k)
- {
- //c为树的层数,L,R为当前节点的区间范围,ql,qr为查询的区间范围,k为查询范围内第k大的数
- if(L==R) //递归出口,返回第k大的数
- return dat[c][L];
- int s; //记录[L,ql-1]中进入左孩子的元素的个数
- int ss; //记录[ql,qr]中进入左孩子的元素的个数
- int mid=(L+R)>>;
- if(L==ql){ //端点重合的情况,单独考虑
- s=;
- ss=sum[c][qr];
- }
- else {
- s=sum[c][ql-];
- ss=sum[c][qr]-s;
- }
- if(k<=ss) //左孩子的元素个数大于k个,说明第k大的元素一定在左孩子区间中,到左孩子中查询
- return query(c+,L,mid,L+s,L+s+ss-,k);
- else
- return query(c+,mid+,R,mid++ql-s-L,mid++qr-s-ss-L,k-ss);
- }
- };
- Divide_tree tree; //定义划分树
- int main()
- {
- int i,L,R,N,M,k;
- scanf("%d%d",&N,&M);
- for(i=;i<=N;i++){ //输入
- scanf("%d",&tree.arr[i]);
- tree.sorted[i]=tree.dat[][i]=tree.arr[i];
- }
- sort(tree.sorted+,tree.sorted+N+);
- tree.build(,,N);
- for(i=;i<=M;i++){ //M次询问
- scanf("%d%d%d",&L,&R,&k);
- printf("%d\n",tree.query(,,N,L,R,k));
- }
- return ;
- }
poj 2104:K-th Number(划分树,经典题)的更多相关文章
- 【POJ 2104】 K-th Number 主席树模板题
达神主席树讲解传送门:http://blog.csdn.net/dad3zz/article/details/50638026 2016-02-23:真的是模板题诶,主席树模板水过.今天新校网不好,没 ...
- POJ2104 K-th Number 划分树 模板题啊
/*Source Code Problem: 2104 User: 96655 Memory: 14808K Time: 1282MS Language: G++ Result: Accepted S ...
- poj 2104 K-th Number 划分树,主席树讲解
K-th Number Input The first line of the input file contains n --- the size of the array, and m --- t ...
- [hdu2665]Kth number(划分树求区间第k大)
解题关键:划分树模板题. #include<cstdio> #include<cstring> #include<algorithm> #include<cs ...
- 静态区间第k大(划分树)
POJ 2104为例[经典划分树问题] 思想: 利用快速排序思想, 建树时将区间内的值与区间中值相比,小于则放入左子树,大于则放入右子树,如果相等则放入左子树直到放满区间一半. 查询时,在建树过程中利 ...
- HDU-2665-Kth number(划分树)
Problem Description Give you a sequence and ask you the kth big number of a inteval. Input The fir ...
- [NBUT 1458 Teemo]区间第k大问题,划分树
裸的区间第k大问题,划分树搞起. #pragma comment(linker, "/STACK:10240000") #include <map> #include ...
- poj 2104 K-th Number (划分树入门 或者 主席树入门)
题意:给n个数,m次询问,每次询问L到R中第k小的数是哪个 算法1:划分树 #include<cstdio> #include<cstring> #include<alg ...
- POJ 2104 K-th Number(划分树)
题目链接 参考HH大神的模版.对其中一些转移,还没想清楚,大体明白上是怎么回事了,划分树就是类似快排,但有点点区别的.多做几个题,慢慢理解. #include <cstdio> #incl ...
- hdu 2665 Kth number (poj 2104 K-th Number) 划分树
划分树的基本功能是,对一个给定的数组,求区间[l,r]内的第k大(小)数. 划分树的基本思想是分治,每次查询复杂度为O(log(n)),n是数组规模. 具体原理见http://baike.baidu. ...
随机推荐
- HDU 1003 动态规划
http://acm.hdu.edu.cn/showproblem.php?pid=1003 这几天开始刷动归题目,先来一道签到题 然而做的并不轻松, 没有注意到边界问题, WA了几发才发现 #inc ...
- tfw格式图解
话不多说,直接看图. 上图中的UV坐标,实际上只的是图像的 横向坐标 和 纵向坐标 .即图像的行和列坐标. 对于图上任意一个像素点(col,row)这个坐标,换算其地理坐标就十分简单. GeoX = ...
- fastx_toolkit软件使用说明
高通量测序数据下机后的原始fastq文件,包含4行,其中一行为质量值,另外一行则为对应序列,我们都了解高通量的数据处理首先要进行质量控制,这些过程包括去接头.过滤低质量reads.去除低质量的3'和5 ...
- Droid4x快照还原
一.问题描述 1. Droid4x还原快照可以通过VirtualBox 先还原快照 2. virtualbox 还原快照之后 如果没有用virtualbox启动 并关闭 而是直接启动Droid ...
- webrtc开源项目音频重采样“不友好接口”的几点总结
WebRTC(Web Real Time Communication)并不是Google原来自己的技术,在2010年,Google以大约6820万美元收购了VoIP软件 开发商Global IP So ...
- history/location操作 /navigator 操作/ screen操作
话说mac真的没广告...就凭这点,mac完胜.ei capitan 好牛畅,分屏很好用啊,回不去了. var hist=window.history; hist.go(param); // para ...
- poj 1789
http://poj.org/problem?id=1789 这是一道图论的题,个人觉得和那个POJ1258是差不多的,就是多了一步,题目难以读懂 题目的意思:就是给你一群字符串要你找字符串对应的字符 ...
- linux多线程下载工具mwget
linux多线程下载工具mwget 经常使用wget进行文件下载,然而wget的处理速度并不如人意.遇到一些国外的站点,经常慢得像蜗牛一般.然而为了解决这个问题,便有了mwget:m表示multi多线 ...
- jquery UI 弹出框
2015-07-17 11:04:38 <div id="reg"></div> <script type="text/javascript ...
- ACM/ICPC 之 数论-费马大定理(HNUOJ 13371)
好歹我是数学专业的学生,还是要写写训练的时候遇到的数学问题滴~~ 在ACM集训的时候在各高校OJ上也遇见过挺多的数学问题,例如大数的处理,素数的各种算法,几何问题,函数问题(单调,周期等性质),甚至是 ...