poj2104 Kth-Number
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
题意:给你一个大小为n的序列和m个询问,每次询问求[L,R]区间第k大的值。
正解:主席树或整体二分
以前一直觉得主席树是一个很高深的东西,自己写了以后才知道原来主席树代码极短。。
建n颗值域线段树,第i颗线段树保存1-i对应区间的结点个数,如根结点为1-maxa的个数,左右儿子分别二分得到。
那么,这颗主席树就能满足前缀和的性质,在查询时,只需将第r颗树上的贡献减去第l-1颗树上的贡献就好。查询贡献时,判断当前两结点之差与k的关系。如果当前差<=k,那么就查询左子树,否则查询右子树,查询到叶子结点时就得出答案。。
还有一个问题,如果真的直接开n颗线段树肯定会MLE,那么我们可以利用可持久化技术,每次插入一棵线段树时只加入与之前的树不同的一条链,其他的结点不变,那么我们每次插入的空间复杂度为O(logN),总复杂度为O(NlogN),可以接受。
不多说了,看代码吧。。
//It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf 1<<30
#define il inline
#define RG register
#define ll long long
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) using namespace std; int root[],a[],num[],hash[],s[],ls[],rs[],n,m,sz,tot; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar(); if (ch=='-') q=,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar(); return q ? -x : x;
} il void insert(RG int l,RG int r,RG int x,RG int &y,RG int k){
y=++sz,s[y]=s[x]+; if (l==r) return; ls[y]=ls[x],rs[y]=rs[x]; RG int mid=(l+r)>>;
if (k<=mid) insert(l,mid,ls[x],ls[y],k); else insert(mid+,r,rs[x],rs[y],k); return;
} il int ask(RG int l,RG int r,RG int x,RG int y,RG int k){
while (l<r){
RG int mid=(l+r)>>;
if (s[ls[y]]-s[ls[x]]>=k) r=mid,x=ls[x],y=ls[y];
else l=mid+,k-=s[ls[y]]-s[ls[x]],x=rs[x],y=rs[y];
}
return l;
} il void work(){
n=gi(),m=gi(); for (RG int i=;i<=n;++i) num[i]=a[i]=gi(); sort(num+,num+n+);
hash[++tot]=num[]; for (RG int i=;i<=n;++i) if (num[i]!=num[i-]) hash[++tot]=num[i];
for (RG int i=;i<=n;++i) insert(,tot,root[i-],root[i],lower_bound(hash+,hash+tot+,a[i])-hash);
for (RG int i=;i<=m;++i){ RG int l=gi(),r=gi(),k=gi(); printf("%d\n",hash[ask(,tot,root[l-],root[r],k)]); }
return;
} int main(){
File("kth");
work();
return ;
}
poj2104 Kth-Number的更多相关文章
- POJ2104 K-th Number —— 区间第k小 整体二分
题目链接:https://vjudge.net/problem/POJ-2104 K-th Number Time Limit: 20000MS Memory Limit: 65536K Tota ...
- poj2104 k-th number 主席树入门讲解
poj2104 k-th number 主席树入门讲解 定义:主席树是一种可持久化的线段树 又叫函数式线段树 刚开始学是不是觉得很蒙逼啊 其实我也是 主席树说简单了 就是 保留你每一步操作完成之后 ...
- POJ2104 K-th Number [整体二分]
题目传送门 K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 69053 Accepted: 24 ...
- POJ2104 K-th Number(主席树)
题目 Source http://poj.org/problem?id=2104 Description You are working for Macrohard company in data s ...
- POJ2104 K-th Number[主席树]【学习笔记】
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 51440 Accepted: 17594 Ca ...
- [POJ2104]K-th Number
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 34048 Accepted: 10810 Ca ...
- [poj2104] K-th Number (主席树)
主席树 Description You are working for Macrohard company in data structures department. After failing y ...
- 主席树:POJ2104 K-th Number (主席树模板题)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 44952 Accepted: 14951 Ca ...
- POJ2104 K-th Number(线段树)
题目链接 K-th Number #include <cstdio> #include <cstring> #include <iostream> #include ...
- POJ2104 K-th Number (子区间内第k大的数字)【划分树算法模板应用】
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 40920 Accepted: 13367 Ca ...
随机推荐
- 机器学习基石 5 Training versus Testing
机器学习基石 5 Training versus Testing Recap and Preview 回顾一下机器学习的流程图: 机器学习可以理解为寻找到 \(g\),使得 \(g \approx f ...
- Jackson注解学习参考(转)
转:http://wong-john.iteye.com/blog/1753402 以下内容摘录.翻译自https://github.com/FasterXML/jackson-annotations ...
- oracle 11g centos6 安装
选型:32位的内存是个瓶颈,已经是64位的时代了.使用64位的CentOS6 和 64位的Oracle 11g R2在虚拟机器安装,采用hostonly方式设置网络注意:能上网的网卡要设置一下ICS( ...
- Onsen UI 前端框架(二)
上一章介绍了OnsenUI一些入门的知识以及它和AngularJS配合的初始化方法.这一章,咱们继续对这块内容进行介绍,对OnsenUI提供的组件进行更进一步的学习. 咱们从手机应用布局的最上面开始. ...
- linux使用LVM合并硬盘
目的将两块空硬盘合并为"一块",挂载到指定目录下,达到在一个目录使用2块硬盘所有空间的效果.条件硬盘1 /dev/sdb 硬盘2 /dev/sdc方法创建pvpvcreate /d ...
- CSS媒体查询适配范例
/*orientation:portrait纵向*/ /*orientation:landscape横向*/ /*iPhone 4*/ @media only screen and (min-devi ...
- sub,dl,dt,排版,横向滚动条,浮动元素居中,box-sizing
1.sub标签 下标 2.dl,dt,dd用的地方通常是具有标题,而标题下对应有若干列表简单的(栏目标题+对应标题列表)和标题对应下面有内容.在使用时候我们能简洁html代码情况下,学会灵活使用dl ...
- Oracle存储过程的调用和执行
1.什么是存储过程: 用于在数据库中完成特定的操作或者任务.是一个PLSQL程序块,可以永久的保存在数据库中以供其他程序调用. 2.无参存储过程的使用: Normal 0 7.8 磅 0 2 fals ...
- UNIX基础上
时光飞逝,转眼已经毕业快2年了,觉得自己学的东西多却不精.对此深深的思考一下,觉得有必要连载unix环境编程文章,以此激励自己学习.在此立贴为证,2天一篇博客从零开始阐述unix的环境编程. 参考书籍 ...
- python操作数据库之批量导入
python操作数据库之批量导入 Python语法简洁清晰,特色之一是强制用空白符(white space)作为语句缩进. Python具有丰富和强大的库.它常被昵称为胶水语言,能够把用其他语言制作的 ...