poj2104(划分树模板)
poj2104
题意
给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数。
分析
划分树模板,O(mlogn)。

- 建树。根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右子树(在子区间内数与数的相对位置保持不变),递归向下分割。
- 查询。toleft[p][i] 表示第 p 层前 i 个数中有多少个整数分入下一层。查询最重要的是确定新的查询区间,若递归查询左区间,则新的子区间的左边一定是上一层区间 [L, l - 1] 里的 toleft[dep][l-1] - toleft[dep][L-1] 个整数,那么 newl = L + toleft[dep][l-1] - toleft[dep][L-1],[l, r] 区间内有cnt = toleft[dep][r] - toleft[dep][l - 1] 个数,所以 newr = newl + cnt - 1;查询右区间则要先确定 newr 的值,[r+1, R] 中有 c = toleft[dep][R] - toleft[dep][r] 个整数位于左子区间的右方,所以查询区间 r 要向右移 c 个数,newr = r + c,newl = newr - (r - l - cnt)。
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int INF = 1e9;
const int MAXN = 1e5 + 5;
const int LOG_N = 30;
// tree[dep][i] 第dep层第i个位置的数值
int tree[LOG_N][MAXN];
int sorted[MAXN];
// toleft[p][i] 第p层前i个数中有多少个整数分入下一层
int toleft[LOG_N][MAXN];
void build(int l, int r, int dep)
{
if(l == r) return;
int mid = (l + r) / 2;
int same = mid - l + 1; // 和中点数相同的数的个数
for(int i = l; i <= r; i++)
if(tree[dep][i] < sorted[mid]) same--;
int lpos = l, rpos = mid + 1;
for(int i = l; i <= r; i++)
{
if(tree[dep][i] < sorted[mid])
tree[dep + 1][lpos++] = tree[dep][i];
else if(tree[dep][i] == sorted[mid] && same)
{
tree[dep + 1][lpos++] = tree[dep][i];
same--;
}
else tree[dep + 1][rpos++] = tree[dep][i];
toleft[dep][i] = toleft[dep][l - 1] + lpos - l;
}
build(l, mid, dep + 1);
build(mid + 1, r, dep + 1);
}
// [L,R]里查询子区间[l,r]第k小的数
int query(int L, int R, int l, int r, int dep, int k)
{
if(l == r) return tree[dep][l];
int mid = (L + R) / 2;
// 有多少个查询区间内的节点会进入下一层的左子树
int cnt = toleft[dep][r] - toleft[dep][l - 1];
if(cnt >= k)
{
int newl = L + toleft[dep][l - 1] - toleft[dep][L - 1];
int newr = newl + cnt - 1;
return query(L, mid, newl, newr, dep + 1, k);
}
else
{
int newr = r + toleft[dep][R] - toleft[dep][r];
int newl = newr - (r - l - cnt);
return query(mid + 1, R, newl, newr, dep + 1, k - cnt);
}
}
int main()
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
for(int i = 1; i <= n; i++)
{
scanf("%d", &sorted[i]);
tree[0][i] = sorted[i];
}
sort(sorted + 1, sorted + n + 1);
build(1, n, 0);
while(m--)
{
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
printf("%d\n", query(1, n, l, r, 0, k));
}
}
return 0;
}
poj2104(划分树模板)的更多相关文章
- poj2104(划分树模板)
poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...
- hdu2665 && poj2104划分树
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 47066 Accepted: 15743 Ca ...
- hdu 2665 Kth number(划分树模板)
http://acm.hdu.edu.cn/showproblem.php?pid=2665 [ poj 2104 2761 ] 改变一下输入就可以过 http://poj.org/problem? ...
- HDU-3743 Minimum Sum,划分树模板
Minimum Sum 被这个题坑了一下午,原来只需找一个最中间的数即可,我以为是平均数. 题意:找一个数使得这个数和区间内所有数的差的绝对值最小.输出最小值. 开始用线段树来了一发果断T了,然后各种 ...
- VIJOS P1081 野生动物园 SBT、划分树模板
[描述] cjBBteam拥有一个很大的野生动物园.这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域都饲养着一头狮子.这些狮子从北到南编号为1,2,3,…,N.每头狮子都有 ...
- poj2104 划分树 区间K大 在线 无修改
博主sbit....对于高级数据结构深感无力,然后这些东西在OI竟然烂大街了,不搞就整个人都不好了呢. 于是我勇猛的跳进了这个大坑 ——sbit 区间K大的裸题,在线,无修改. 可以用归并树(\(O( ...
- poj 2104 (划分树模板)
Description You are working for Macrohard company in data structures department. After failing your ...
- POJ2104 K-th Number 划分树 模板题啊
/*Source Code Problem: 2104 User: 96655 Memory: 14808K Time: 1282MS Language: G++ Result: Accepted S ...
- poj2104 主席树模板题
题意 给出n个数字组成的数字序列,有m组询问.每次询问包含三个数字l,r,k.对于每个询问输出序列区间[l,r]中第k大的数字. 分析 这是主席树的模板题,套板子就可以 #include <cs ...
随机推荐
- 《Cracking the Coding Interview》——第12章:测试——题目1
2014-04-24 23:10 题目:找出下面代码里的错误. 解法:请看下面. 代码: // 12.1 What's wrong with the following code segment? # ...
- Django笔记 —— 模型
最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...
- postman导出excel出现response
https://jingyan.baidu.com/article/915fc414559b4351394b2084.html
- springboot整合jersey
https://blog.csdn.net/xiongpei00/article/details/76576420
- django-settings里mysql连接配置
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'dailyfresh', 'HOST': 'loca ...
- Python网络编程(OSI模型、网络协议、TCP)
前言: 什么是网络? 网络是由节点和连线构成,表示诸多对象及其相互联系. 在数学上,网络是一种图,一般认为专指加权图. 网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类 型的实际问题中抽象 ...
- python 由递归的dict构建树的画图代码
createPlot(mytree)方法实现. 其中myTree是一个字典,调用retrieveTree(0)可以获得一个字典的样式. Last login: Thu Feb 23 19:07:53 ...
- HDU 3577 Fast Arrangement ( 线段树 成段更新 区间最值 区间最大覆盖次数 )
线段树成段更新+区间最值. 注意某人的乘车区间是[a, b-1],因为他在b站就下车了. #include <cstdio> #include <cstring> #inclu ...
- 团队冲刺Alpha(九)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...
- LeetCode -- Valid Parenthese
Question: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine i ...