K-th Number POJ - 2104
K-th Number POJ - 2104
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
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include<queue>
using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = 1e5+;
const int mod = 1e9+; int n,q,m,tot;
int a[maxn],t[maxn],T[maxn],lson[maxn*],rson[maxn*],c[maxn*]; void Init_hash()
{
for(int i=;i<=n;i++)
t[i] = a[i];
sort(t+,t++n);
m = unique(t+,t++n)-t-;
} int build(int l,int r)
{
int root = tot++;
c[root] = ;
if (l != r)
{
int mid = (l+r) >> ;
lson[root] = build(l,mid);
rson[root] = build(mid+,r);
}
return root;
}
int Hash(int x)
{
return lower_bound(t+,t++m,x)-t;
}
int update(int root,int pos,int val)
{
int newroot = tot ++,tmp = newroot;
c[newroot] = c[root] + val;
int l = ,r = m;
while(l <r)
{
int mid = (l+r)>>;
if(pos <= mid)
{
lson[newroot] = tot++;
rson[newroot] = rson[root];
newroot = lson[newroot];
root = lson[root];
r = mid;
}
else
{
rson[newroot] = tot ++;
lson[newroot] = lson[root];
newroot = rson[newroot];
root = rson[root];
l = mid + ;
}
c[newroot] = c[root] + val;
}
return tmp; }
int query(int left_root,int right_root,int k)
{
int l = ,r = m;
while(l < r)
{
int mid = (l+r) >> ;
if(c[lson[left_root]] - c[lson[right_root]] >= k)
{
r = mid;
left_root = lson[left_root];
right_root = lson[right_root];
}
else
{
l = mid + ;
k -= c[lson[left_root]] - c[lson[right_root]];
left_root = rson[left_root];
right_root = rson[right_root];
}
}
return l;
}
int main()
{
scanf("%d%d",&n,&q);
tot = ;
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
Init_hash();
T[n+] = build(,m);
for(int i=n;i;i--)
{
int pos = Hash(a[i]);
T[i] = update(T[i+],pos,);
}
while(q--)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",t[query(T[l],T[r+],k)]);
}
}
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<stack>
#include<cstdlib>
#include<queue>
#include<set>
#include<string.h>
#include<vector>
#include<deque>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define eps 1e-4
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
typedef long long LL;
typedef long long ll;
const int maxn = 2e5 + ;
const int mod = ;
int n,m,a[maxn],root[maxn],cnt;
vector<int>v;
struct node{
int l,r,sum;
}T[maxn * ];
int getid(int x) {
return lower_bound(v.begin(),v.end(),x) - v.begin() + ;
}
void update(int l,int r,int &x,int y,int pos) {
T[++cnt] = T[y],T[cnt].sum ++,x = cnt;
if(l == r) return;
int mid = (l + r) / ;
if(mid >= pos) update(l,mid,T[x].l,T[y].l,pos);
else update(mid + ,r,T[x].r,T[y].r,pos);
}
int query(int l,int r,int x,int y,int k) {
if(l == r) return l;
int mid = (l + r) / ;
int sum = T[T[y].l].sum - T[T[x].l].sum;
if(sum >= k) return query(l,mid,T[x].l,T[y].l,k);
else return query(mid + ,r,T[x].r,T[y].r,k - sum);
}
void init() {
cnt = ;
memset(root,,sizeof root);
}
int main()
{
init();
scanf("%d %d",&n,&m);
for (int i = ; i <= n; ++i) {
scanf("%d",&a[i]);
v.push_back(a[i]);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
for (int i = ; i <= n; ++i)
update(,n,root[i],root[i - ],getid(a[i]));
for (int i = ; i <= m; ++i) {
int x,y,k;
scanf("%d %d %d",&x, &y, &k);
printf("%d\n",v[query(,n,root[x - ],root[y],k) - ]);
}
}
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<stack>
#include<cstdlib>
#include<queue>
#include<set>
#include<string.h>
#include<vector>
#include<deque>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define eps 1e-4
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
typedef long long LL;
typedef long long ll;
const int maxn = 2e5 + ;
const int mod = ;
int n,m,a[maxn],root[maxn],cnt;
/*
root:代表每个历史版本线段树的根节点位置
cnt:用作开辟新的树节点
*/
vector<int>v;
struct node{
int l,r,sum;
}T[maxn * ]; //线段树区间统计,sum代表在这个区间数的个数
int getid(int x) { //获取离散数组后的下标
return lower_bound(v.begin(),v.end(),x) - v.begin() + ;
}
/*
update函数:
y代表前一棵树的节点位置,x是后面的节点位置
*/
void update(int l,int r,int &x,int y,int pos) {
//&x 引用节点指针扩展新节点
T[++cnt] = T[y],T[cnt].sum ++,x = cnt; //新开节点,将需要修改的树节点复制到新开辟节点,改变自己的sum
if(l == r) return;
int mid = (l + r) / ;
if(mid >= pos) update(l,mid,T[x].l,T[y].l,pos); //节点左边
else update(mid + ,r,T[x].r,T[y].r,pos); //节点右边
}
int query(int l,int r,int x,int y,int k) {
if(l == r) return l;
int mid = (l + r) / ;
int sum = T[T[y].l].sum - T[T[x].l].sum; //两颗线段树sum做差
if(sum >= k) return query(l,mid,T[x].l,T[y].l,k); //如果当前的结点个数sum比k要大的话,说明第k大的结点在左子树当中,就去遍历左子树
else return query(mid + ,r,T[x].r,T[y].r,k - sum); //如果当前的结点个数sum比k要小的话,说明第k大的结点在右子树当中,而左子树的结点个数是sum个,那就去找右子树中的第k-sum的数
}
void init() {
cnt = ;
memset(root,,sizeof root);
}
int main()
{
init();
scanf("%d %d",&n,&m);
for (int i = ; i <= n; ++i) {
scanf("%d",&a[i]);
v.push_back(a[i]); //离散化数组
}
sort(v.begin(),v.end()); //离散化数组
v.erase(unique(v.begin(),v.end()),v.end()); //离散化数组 for (int i = ; i <= n; ++i) {
update(, n, root[i], root[i - ], getid(a[i]));
}
for (int i = ; i <= m; ++i) {
int x,y,k;
scanf("%d %d %d",&x, &y, &k);
printf("%d\n",v[query(,n,root[x - ],root[y],k) - ]);
}
}
K-th Number POJ - 2104的更多相关文章
- K-th Number Poj - 2104 主席树
K-th Number Poj - 2104 主席树 题意 给你n数字,然后有m次询问,询问一段区间内的第k小的数. 解题思路 这个题是限时训练做的题,我不会,看到这个题我开始是拒绝的,虽然题意清晰简 ...
- 主席树 【权值线段树】 && 例题K-th Number POJ - 2104
一.主席树与权值线段树区别 主席树是由许多权值线段树构成,单独的权值线段树只能解决寻找整个区间第k大/小值问题(什么叫整个区间,比如你对区间[1,8]建立一颗对应权值线段树,那么你不能询问区间[2,5 ...
- K-th Number POJ - 2104 划分树
K-th Number You are working for Macrohard company in data structures department. After failing your ...
- HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- AC日记——K-th Number poj 2104
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 52348 Accepted: 17985 Ca ...
- hdu 2665 Kth number (poj 2104 K-th Number) 划分树
划分树的基本功能是,对一个给定的数组,求区间[l,r]内的第k大(小)数. 划分树的基本思想是分治,每次查询复杂度为O(log(n)),n是数组规模. 具体原理见http://baike.baidu. ...
- POJ 2104&HDU 2665 Kth number(主席树入门+离散化)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 50247 Accepted: 17101 Ca ...
- poj 2104 K-th Number 主席树+超级详细解释
poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...
- poj 2104 K-th Number(主席树,详细有用)
poj 2104 K-th Number(主席树) 主席树就是持久化的线段树,添加的时候,每更新了一个节点的线段树都被保存下来了. 查询区间[L,R]操作的时候,只需要用第R棵树减去第L-1棵树就是区 ...
随机推荐
- ajax post方式表单提交的注意事项。
当我们创建一个异步对象XMLHttpRequest同时post方式向后台传输数据的时候. 我们要设置异步对象的xhr.setRequestHeader成员的值为 XMLHttpRequest.setR ...
- CAS登录认证的简单介绍
参考博客: https://www.jianshu.com/p/8daeb20abb84 下面是CAS最基本的协议过程: 下面是CAS Web工作流程图: 名词解释 Ticket Grangting ...
- 红象云腾CRH 一键部署大数据平台
平台: arm 类型: ARM 模板 软件包: azkaban hadoop 2.6 hbase hive kafka spark zeppelin azkaban basic software bi ...
- DELL R730安装ESXI虚拟化
dell安装esxi需要dell官方提供的镜像文件地址:http://www.dell.com/support/article/us/en/04/SLN290857/dell%E5%AE%9A%E5% ...
- jenkins代码自动部署
jenkins是一个广泛用于持续构建的可视化web工具,持续构建说得更直白点,就是各种项目的"自动化"编译.打包.分发部署.jenkins可以很好的支持各种语言(比如:java, ...
- Java 使用正则表达式取出图片地址以及跳转的链接地址,来判断死链(一)
任务:通过driver的getPageSource()获取网页的源码内容,在把网页中图片链接地址和跳转的url地址进行过滤,在get每个请求,来判断是否是死链 如图: 获取网页源码中所有的href,以 ...
- 【转】IOS基础:深入理解Objective-c中@class的含义
objective-c中,当一个类使用到另一个类时,并且在类的头文件中需要创建被引用的指针时, 如下面代码: A.h文件 #import "B.h" @interface A : ...
- FreeRTOS_软件定时器
FreeRTOS 软件定时器 实验 创建2个任务,start_task.timercontrol_task. start_stask:创建timercontrol_task任务:创建周期定时器Auto ...
- 完全用 Linux 工作
GNU/Linux 不是每個人都想用的.如果你只需要處理一般的事務,玩遊戲,那就不需要了解 Linux. UNIX 比 Windows 更適合用於科學研究工作. 大多數科學家和工程師以 UNIX 作為 ...
- 文件系统 - Linux 支持的文件系统类型
NAME 文件系统 - Linux 支持的文件系统类型:minix, ext, ext2, xia, msdos, umsdos, vfat, proc, nfs, iso9660, hpfs, sy ...