题目链接:http://poj.org/problem?id=2104

K-th Number
Time Limit: 20000MS   Memory Limit: 65536K
Total Submissions: 74919   Accepted: 26808
Case Time Limit: 2000MS

Description

You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment. 
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 first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000). 
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

For each question output the answer to it --- the k-th number in sorted a[i...j] segment.

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

This problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed.

Source

Northeastern Europe 2004, Northern Subregion
题目大意:求区间第K小的数
思路:主席树入门经典题
看代码:
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn=1e5+5;
vector<int>v;
int cnt,root[maxn],a[maxn];
int sz;
struct Tree
{int l,r,sum;//左右儿子 多少个数
}T[maxn<<5];
void Init()
{cnt=0;T[cnt].l=T[cnt].r=T[cnt].sum=0;root[cnt]=0;v.clear();
}
int getid(int x)//去重后排第几
{return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void Update(int l,int r,int &x,int y,int pos)//x是新树 y是上一颗树
{T[++cnt]=T[y],T[cnt].sum++,x=cnt;//复制上一颗树 节点个数加一 记下根节点if(l==r) return ;//到了叶子节点int mid=(l+r)>>1;//pos是当前数在原数列中的大小排序//小于等于中间值 往左放if(pos<=mid) Update(l,mid,T[x].l,T[y].l,pos);else Update(mid+1,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)>>1;int sum=T[T[y].l].sum-T[T[x].l].sum;//两者之间小于中间值的个数//个数大于等于K个 证明答案在小于mid的一边 也就是左边if(sum>=k) return Query(l,mid,T[x].l,T[y].l,k);else return Query(mid+1,r,T[x].r,T[y].r,k-sum);
}
int main()
{Init();int N,M;scanf("%d%d",&N,&M);for(int i=1;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());//去重sz=v.size();for(int i=1;i<=N;i++) Update(1,sz,root[i],root[i-1],getid(a[i]));//按照输入顺序插入 建树int l,r,k;while(M--){scanf("%d%d%d",&l,&r,&k);printf("%d\n",v[Query(1,sz,root[l-1],root[r],k)-1]);}return 0;
}

另一种形式代码:

#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn=1e5+5;
vector<int>v;
int sz;
int cnt,root[maxn],a[maxn];
struct Tree
{int l,r,sum;//左右儿子 多少个数
}T[maxn<<5];
void Init()
{cnt=0;T[cnt].l=T[cnt].r=T[cnt].sum=0;root[cnt]=0;v.clear();
}
int getid(int x)//去重后排第几
{return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
int Update(int l,int r,int y,int pos)//x是新树 y是上一颗树
{int p=++cnt;T[p]=T[y],T[cnt].sum++;//复制上一颗树 节点个数加一 记下根节点if(l==r) return p;//到了叶子节点int mid=(l+r)>>1;//pos是当前数在原数列中的大小排序//小于等于中间值 往左放if(pos<=mid) T[p].l=Update(l,mid,T[y].l,pos);else T[p].r=Update(mid+1,r,T[y].r,pos);return p;
}
int Query(int l,int r,int x,int y,int k)
{if(l==r) return l;//到了叶子节点 答案肯定是叶子节点int mid=(l+r)>>1;int sum=T[T[y].l].sum-T[T[x].l].sum;//两者之间小于中间值的个数//个数大于等于K个 证明答案在小于mid的一边 也就是左边if(sum>=k) return Query(l,mid,T[x].l,T[y].l,k);else return Query(mid+1,r,T[x].r,T[y].r,k-sum);
}
int main()
{Init();int N,M;scanf("%d%d",&N,&M);for(int i=1;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());//去重sz=v.size();for(int i=1;i<=N;i++) root[i]=Update(1,sz,root[i-1],getid(a[i]));//按照输入顺序插入 建树int l,r,k;while(M--){scanf("%d%d%d",&l,&r,&k);printf("%d\n",v[Query(1,sz,root[l-1],root[r],k)-1]);}return 0;
}

转载于:https://www.cnblogs.com/caijiaming/p/11265965.html

K-th Number相关推荐

  1. K - The Number of Products

    K - The Number of Products 题目入口:K - The Number of Products Codeforces:B. The Number of Products 参考网站 ...

  2. leetcode 476. 数字的补数(Java版)| How to extract ‘k’ bits from a given position in a number

    题目 https://leetcode-cn.com/problems/number-complement/ 思路 我们想要返回已知数字的补数(num>=1). 思路: 获取 num 的二进制数 ...

  3. 和至少为k的最短子数组 python_LeetCode 862. 和至少为 K 的最短子数组

    最近刷LeetCode题目的一些思路,题目信息 返回A 的最短的非空连续子数组的长度,该子数组的和至少为 K .如果没有和至少为 K 的非空子数组,返回 -1 . 示例 1:输入:A = [1], K ...

  4. POJ3111 K Best —— 01分数规划 二分法

    题目链接:http://poj.org/problem?id=3111 K Best Time Limit: 8000MS   Memory Limit: 65536K Total Submissio ...

  5. 斯坦福CS231n项目实战(一):k最近邻(kNN)分类算法

    我的网站:红色石头的机器学习之路 我的CSDN:红色石头的专栏 我的知乎:红色石头 我的微博:RedstoneWill的微博 我的GitHub:RedstoneWill的GitHub 我的微信公众号: ...

  6. K for the Price of One(EASY HARD)

    This is the easy version of this problem. The only difference is the constraint on k - the number of ...

  7. 数组中的第K个最大元素

    数组中的第K个最大元素 在未排序的数组中找到第k个最大的元素.请注意,你需要找的是数组排序后的第k个最大的元素,而不是第k个不同的元素. 示例 输入: [3,2,1,5,6,4] 和 k = 2 输出 ...

  8. K BEST(最大化平均值)

    K BEST(最大化平均值) Demy has n jewels. Each of her jewels has some value vi and weight wi.Since her husba ...

  9. 给定n位正整数a,去掉其中任意k个数字后,剩下的数字按原次序排列组成⼀个新的正整数,求组成的新数最小的删数方案(O((n-k)logk)优化)

    问题描述 给定n位正整数a,去掉其中任意k个数字后,剩下的数字按原次序排列组成⼀个新的正整数.对于给定的n和k,设计⼀个算法,找出剩下数字组成的新数最少的删数方案. 这一道题来自zyq老师的算法分析与 ...

  10. 15.CUDA编程手册中文版---附录K CUDA计算能力

    附录K CUDA计算能力 更多精彩内容,请扫描下方二维码或者访问https://developer.nvidia.com/zh-cn/developer-program 来加入NVIDIA开发者计划 ...

最新文章

  1. 聊一个不常见的面试题:为什么数据库连接池不采用 IO 多路复用?
  2. 辽宁鞍山与中国联通签订智慧城市大数据云计算中心项目
  3. 时间序列(七): 高冷贵族: 隐马尔可夫模型
  4. linux 查看其他磁盘分区,Linux 查看磁盘分区.pdf
  5. 关于产品经理如何准备面试,我有三点想法
  6. Elasticsearch分布式机制探究
  7. mac qt编译出现问题的解决方法
  8. 网络编程1-初探winSocket
  9. html 怎么看版本号,怎样查看jquery版本号?
  10. ms08067 分析与利用
  11. linux之U盘读写速度测试
  12. Unity常用图片格式说明
  13. 解读制造业数字化转型的六大因素
  14. 第13章WEB13-JSP模式JDBC高级篇
  15. chm文档制作 java_自己动手制作chm格式开源文档
  16. 《迅雷链精品课》第四课:区块链技术的发展趋势
  17. 基于jquery复刻一个月饼版地狱死神小游戏
  18. 关于网易云音乐代码音乐播放器单曲和歌单的调用
  19. 产品名称:iWX JAVA微信管理平台源码-微友1314
  20. 贝叶斯网络的python实现:Monty Hall问题的求解

热门文章

  1. cognos安装过程各种问题跟解决方法
  2. 因下面文的损坏或丢失windows/system32/config/system 解决方法
  3. 【报告分享】B2B内容营销指南—制定有效内容策略-领英.pdf(附下载链接)
  4. 深度学习基础 | NLP大魔王 · BERT
  5. 【论文】Awesome Relation Extraction Paper(关系抽取)(PART III)
  6. TensorFlow图像数据预处理
  7. php设计一个盒子类代码_PHP设计模式之简单工厂模式(Simple Factory)代码实例大全(七)...
  8. Leetcode每日一题:29.divide-two-integers(两数相除)
  9. ROS入门-16.tf坐标系广播与监听的编程实现
  10. Java虚拟机(三)——类文件结构