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. MySQL事务原理浅析

    前言​ 因为自己对数据的可靠性,可用性方面特别感兴趣,所以在MySQL事务方面看了很多资料,也看了很多博客,所以想到自己也写一篇博客整理整理自己所学内容,尽量用自己的语言解释得通俗易懂. 事务经典场景 ...

  2. Scratch编程:游来游去的鱼(二)

    “ Scratch编程学习环境搭建好了吗?让我们一起来进行游戏吧!” 01 — 游戏介绍 这是一款简单的小游戏,实现了一条小鱼在池塘里游来游去. 02 — 设计思路 1,这个游戏主要由一个池塘背景和一 ...

  3. Lambda 表达式动态拼接.

    背景: 项目使用EF 查询时需要手动判断条件写.觉得太麻烦就Google 如何动态生成Linq.最后找到了 System.Linq.Dynamic.Core. 这个东西. Scott Guthrie ...

  4. python——操作系统的发展史

    一.手工操作 —— 穿孔卡片 1946年第一台计算机诞生--20世纪50年代中期,计算机工作还在采用手工操作方式.此时还没有操作系统的概念.    程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入 ...

  5. falcon 数据丢失处理方法参考

    背景:使用 netstat -ano | grep ESTABLISH | grep 11883 监控 send_Q 和 recv_Q 的值,由于单次推送数据量在1w条以上,导致falcon-agen ...

  6. python数据统计出海品牌

    当国内市场处于红海之中时,市场全球化已成为大势所趋.越来越多的国产品牌远走高飞,纷纷将品牌拿出来. 2019年,中国品牌十大品牌中,华为品牌力指数同比增长22%,阿里巴巴品牌力指数增长48%,小米品牌 ...

  7. vue打包后.woff字体文件路径问题处理

    在执行 npm run build 命令打包后,如果出现 .woff 等字体文件找不到的情况 通过设置 vue-style-loader 打包前缀路径解决

  8. Django 中使用权限认证

    权限认证 权限概念 """ 在实际开发中,项目中都有后台运营站点,运营站点里面会存在多个管理员, 那么不同的管理员会具备不同的任务和能力,那么要实现这样的管理员功能,那么 ...

  9. Bootstrap学习地址

    第一步:https://www.runoob.com/bootstrap/bootstrap-tutorial.html  //菜鸟教程 第二步:https://v3.bootcss.com/gett ...

  10. CentOS6和7启动流程

    CentOS6启动流程 https://linux.cn/article-8807-1.html BIOS 开机自检,硬件自检 MBR MBR磁盘分区是一种使用最为广泛的分区结构,它也被称为DOS分区 ...