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棵树就是区 ...
随机推荐
- JSP标签和JSTL标签注意点
1.转发和重定向问题 当前项目:/Test 转发路径:"/"根目录表示当前项目"/Test","/login.jsp"就是"/Te ...
- SpringBoot | 第二章:lombok介绍及简单使用
在去北京培训的时候,讲师说到了lombok这个第三方插件包,使用了之后发现,确实是个神奇,避免了编写很多臃肿的且定式的代码,虽然现代的IDE都能通过快捷键或者右键的方式,使用Generate Gett ...
- 服务器部署nginx报错 nginx: [warn] conflicting server name "localhost" on xxx.xxx.xxx.xxx:80, ignored
问题 修改nginx配置参数后,使用nginx -t检查配置. 提示successfull后就可以使用 nginx -s reload来重新加载配置 我配置的过程中遇到这样的问题,就是绑定了主机名后, ...
- spring的工厂方法
http://blog.csdn.net/nvd11/article/details/51542360
- HTTP缓存技术,304和200有何区别
为什么有的缓存是 200 OK (from cache),有的缓存是 304 Not Modified 呢?很简单,看运维是否移除了 Entity Tag.移除了,就总是 200 OK (from c ...
- 一个容易被忽视的css选择器
之前学的的迷糊了,也不知道什么会什么不会了,跑去面试了.别人列出一堆css选择器,本以为选择器没啥的,结果到那个多类选择器翻车了,.a.b选择同时含a,b类名的,很尴尬所以回来仔细整理了一下.目前根据 ...
- uvm_analysis_port——TLM1事务级建模方法(二)
UVM中的TLM1端口,第一类是用于uvm_driver 和uvm_sequencer连接端口,第二类是用于其他component之间连接的端口,如uvm_monitor和uvm_scoreboard ...
- Android商城开发系列(十三)—— 首页热卖商品布局实现
热卖商品布局效果如下图: 这个布局跟我们上节做的推荐是一样的,也是用LinearLayout和GridView去实现的,新建一个hot_item.xml,代码如下所示: <?xml versio ...
- jQuery-动画animate() 方法操作 CSS 属性
语法: $(selector).animate({params},speed,callback); 多个params 之间用逗号(,)隔开. 必须使用 Camel 标记法书写所有的属性名,比如,必须使 ...
- 交互ajax
原生的js封装ajax1.创建ajax对象var oAjax=new XMLHttpRequest();//不兼容IE6var oAjax=new ActiveXobject('Microsoft.X ...