K-th Number

Time Limit: 20000MS Memory Limit: 65536K

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<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100001
using namespace std;
int n,m,root[MAXN],cut,a[MAXN],s[MAXN];
struct data{int lc,rc,ans;}tree[MAXN*20];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void add(int &now,int last,int l,int r,int x)
{
now=++cut;tree[now].ans=tree[last].ans+1;
tree[now].lc=tree[last].lc,tree[now].rc=tree[last].rc;
if(l==r) return ;
int mid=(l+r)>>1;
if(x<=mid) add(tree[now].lc,tree[last].lc,l,mid,x);
else add(tree[now].rc,tree[last].rc,mid+1,r,x);
return ;
}
int query(int L,int R,int l,int r,int x)
{
if(l==r) return l;
int p=tree[tree[R].lc].ans-tree[tree[L].lc].ans;//左树中数的个数.
int mid=(l+r)>>1;
if(p>=x) return query(tree[L].lc,tree[R].lc,l,mid,x);
else return query(tree[L].rc,tree[R].rc,mid+1,r,x-p);
}
int main()
{
int t;
int x,y,z;//t=read();
while(scanf("%d%d",&n,&m)!=EOF)
//(t--)
{
n=read(),m=read();
cut=0;memset(root,0,sizeof root);
for(int i=1;i<=n;i++) s[i]=a[i]=read();
sort(s+1,s+n+1);
for(int i=1;i<=n;i++)
{
int p=lower_bound(s+1,s+n+1,a[i])-s;
add(root[i],root[i-1],1,n,p);
}
while(m--)
{
x=read(),y=read(),z=read();
//z=(y-x+1)-z+1;
int p=query(root[x-1],root[y],1,n,z);
printf("%d\n",s[p]);
}
}
return 0;
}
/*
求静态区间第K小.
整体二分.
二分出一个答案然后统计贡献.
对多个操作同时处理.
然后使操作有序化.
树状数组维护一段值域区间内数的个数.
还是比较模糊orz.
*/
#include<iostream>
#include<cstdio>
#define MAXN 200001
#define INF 1e9
using namespace std;
struct data{int x,y,k,s,o,cut;}
q[MAXN],tmp1[MAXN],tmp2[MAXN];
int n,m,tot,s[MAXN],ans[MAXN],a[MAXN],tmp[MAXN];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void add(int x,int z)
{
while(x<=n) s[x]+=z,x+=x&-x;
return ;
}
int getsum(int x)
{
int sum=0;
while(x>0) sum+=s[x],x-=x&-x;
return sum;
}
void slove(int head,int tail,int l,int r)
{
if(head>tail) return ;
if(l==r)
{
for(int i=head;i<=tail;i++)
if(q[i].o==3) ans[q[i].s]=l;
return ;
}
int mid=(l+r)>>1;
for(int i=head;i<=tail;i++)//统计贡献.
{
if(q[i].o==1&&q[i].y<=mid) add(q[i].x,1);
else if(q[i].o==3) tmp[i]=getsum(q[i].y)-getsum(q[i].x-1);
}
for(int i=head;i<=tail;i++)
if(q[i].y<=mid&&q[i].o==1) add(q[i].x,-1);
int l1=0,l2=0;
for(int i=head;i<=tail;i++)
{//检验 对于该操作找一个所属答案位置.
if(q[i].o==3)
{
if(q[i].cut+tmp[i]>=q[i].k) tmp1[++l1]=q[i];
//ans 偏大 放入[l,mid]区间查询.
else q[i].cut+=tmp[i],tmp2[++l2]=q[i];
//ans 偏小 放入[mid+1,r]区间查询.
}
else
{
if(q[i].y<=mid) tmp1[++l1]=q[i];
else tmp2[++l2]=q[i];
}
}
for(int i=1;i<=l1;i++) q[head+i-1]=tmp1[i];
for(int i=1;i<=l2;i++) q[head+l1+i-1]=tmp2[i];
slove(head,head+l1-1,l,mid),slove(head+l1,tail,mid+1,r);
return ;
}
int main()
{
int x,y,z,t=0;char ch[11];
n=read(),m=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
q[++tot].x=i,q[tot].y=a[i];
q[tot].o=1,q[tot].s=0;
}
while(m--)
{
x=read(),y=read(),z=read();
q[++tot].x=x,q[tot].y=y,q[tot].k=z;
q[tot].o=3;q[tot].s=++t;
}
slove(1,tot,-INF,INF);
for(int i=1;i<=t;i++) printf("%d\n",ans[i]);
return 0;
}

Poj 2104 K-th Number(主席树&&整体二分)的更多相关文章

  1. 【POJ 2104】 K-th Number 主席树模板题

    达神主席树讲解传送门:http://blog.csdn.net/dad3zz/article/details/50638026 2016-02-23:真的是模板题诶,主席树模板水过.今天新校网不好,没 ...

  2. 静态区间第k大(主席树)

    POJ 2104为例(主席树入门题) 思想: 可持久化线段树,也叫作函数式线段树,也叫主席树(高大上). 可持久化数据结构(Persistent data structure):利用函数式编程的思想使 ...

  3. poj 2104 K-th Number 主席树+超级详细解释

    poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...

  4. poj2104 k-th number 主席树入门讲解

    poj2104 k-th number 主席树入门讲解 定义:主席树是一种可持久化的线段树 又叫函数式线段树   刚开始学是不是觉得很蒙逼啊 其实我也是 主席树说简单了 就是 保留你每一步操作完成之后 ...

  5. POJ 2104 K-th Number 主席树(区间第k大)

    题目链接: http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MSMemory Limit: 65536K 问题描述 You ar ...

  6. POJ 2104 K-th Number ( 求取区间 K 大值 || 主席树 || 离线线段树)

    题意 : 给出一个含有 N 个数的序列,然后有 M 次问询,每次问询包含 ( L, R, K ) 要求你给出 L 到 R 这个区间的第 K 大是几 分析 : 求取区间 K 大值是个经典的问题,可以使用 ...

  7. POJ 2104:K-th Number(主席树静态区间k大)

    题目大意:对于一个序列,每次询问区间[l,r]的第k大树. 分析: 主席树模板题 program kthtree; type point=record l,r,s:longint; end; var ...

  8. SPOJ MKTHNUM & POJ 2104 - K-th Number - [主席树模板题]

    题目链接:http://poj.org/problem?id=2104 Description You are working for Macrohard company in data struct ...

  9. poj 2104 K-th Number(主席树 视频)

    K-th Number 题意: 给你一些数,让你求一个区间内,第k大的数是多少. 题解: 主席树第一题,看的qsc视频写的,戳戳戳 学到了unique函数,他的作用是:把相邻的重复的放到后面,返回值是 ...

随机推荐

  1. 网络地址转换(NAT)

    NAT是解决ipv4地址短缺的方案之一 NAT是将位于子网中的主机与外网连通,子网中所有的主机都可以通过路由器的网络地址转换访问外网.对于外网来说该路由器相当于一台完整的主机,子网内所有主机对外网的访 ...

  2. java-version不是内部或外部命令的问题

    有时java-version的错误并不一定是环境配置的问题 ,可能是粗心的问题 运行——cmd——输入java -version 看清.java命令后是有个空格的 -version应该只是参数而已 我 ...

  3. 撸一个 vue 的截图组件,按比例截取

    <template> <div class="clip-img" :style="imgStyle"> <img :src=&qu ...

  4. js中__proto__和prototype的区别和关系?(转)

    转自知乎:https://www.zhihu.com/question/34183746

  5. Centos6 r8192ce_pci

    Centos6 r8192ce_pci # # yum install epel-release# yum-config-manager --enable rhui-REGION-rhel-serve ...

  6. 2019.9.27,SAP成都研究院数字创新空间团队建设,射箭和游泳

    2019年9月27日,秋高气爽,SAP成都研究院数字创新团队全体成员又迎来了一次团队建设活动.这次的主题是:射箭. 在正式活动之前,大家先享用了一顿泰式海鲜火锅: 吃饱喝足之后,我们来到了名为&quo ...

  7. java引用传递和值传递

    关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习 ...

  8. Harbor高可用理论及实践(汇聚篇)

    目录 一.理论概述 什么是harbor harbor要解决的问题 有了docker自带的registry为什么还要用harbor harbor的架构组件 Harbor工作原理 二.部署harbor及其 ...

  9. 【华为云】MRS journey node HDFS 不一致

    HDFS JournalNode数据不同步告警 恢复指导 1 停止有问题的 JN 实例 2 清楚无效数据 登录有问题JN的后台,使用omm用户操作以下命令: cd /srv/BigData/journ ...

  10. kubernetes集群初始化(二)

    参考地址:https://github.com/unixhot/salt-kubernetes 一.系统初始化 1.1.安装docker 所有节点都安装docker,设置docker国内yum源 [r ...