【POJ2104】【HDU2665】K-th Number

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.
题意:n个数,m次询问,每次求区间[l,r]中的第k小的数
题解:主席树模板(什么是主席树?)
主席树也叫可持久化线段树、函数式线段树,我感觉就跟动态开点线段树差不多(什么是动态开点线段树?)
正常的线段树就是lson=x<<1,rson=x<<1|1,但动态开点线段树不同,它的节点的左右儿子是即用即开的,并用数组记录,每搜到一个点,如果以前没开过,就新开一个点,然后继续搜。这样我们就可以将多个线段树放到一起(怎么做?)
如果许多互部重叠线段树都建在[1,n]这个区间上,那么我们就可以直接将他们都放到一起,分别记录每棵线段树的根root[i],然后正常的在线段树上搞,当需要用到一段没开过的区间时,就新开一个点记录这个区间,然后继续向下查询,如果需要就在开新的点。这样我们可以对每棵线段树进行操作,空间复杂度O(nlogn)
好了,下面说主席树,主席树当然也要动态开点,建n棵线段树(都是权值线段树),不过第i棵线段树保存的是[1,i]这段区间,也就相当于一个前缀(那空间复杂度岂不是O(n^2)?)
于是我们发现,这一堆线段树其实有很大一部分是重复的,比如第i棵线段树,它相当于第i-1棵线段树中新开了一个点a[i],那么如果a[i]在[1,mid]这段区间里,那么第i棵线段树和第i-1课线段树的[mid+1,r]这段区间就是完全相同的!于是我们直接让他们共用这段区间即可(方法:把root[i]的右儿子指针指到root[i-1]的右儿子上,仅新建一个root[i]的左儿子)。同理,如果a[i]在[mid+1,r]这段区间里,我们就让他们共用左儿子,然后继续这样做,直到l==r。于是空间复杂度:O(nlogn)
那查询的时候该怎么做呢,对于本题,[l,r]中的第k小,那么我们已经处理出了[1,r]和[1,l-1]这两棵线段树,那么我们将这两棵线段树相减(因为是权值线段树,所以将每个点都相减即可),就相当于得到了一棵新的线段树[l,r],然后再求整体的第k小(这就很简单了吧)
上面说的这些也不算详解吧,其实就是我个人对主席树的一些理解罢了。
注意:可能有负数
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=100010;
struct node
{
int ls,rs,siz;
}s[4000010];
struct NUM
{
int num,org;
}v[maxn];
int n,m,tot,nm;
int root[maxn],ref[maxn];
bool cmp1(NUM a,NUM b)
{
return a.num<b.num;
}
bool cmp2(NUM a,NUM b)
{
return a.org<b.org;
}
int readin()
{
int ret=0,f=1; char gc;
while(gc<'0'||gc>'9') {if(gc=='-')f=-f;gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void pushup(int x)
{
s[x].siz=s[s[x].ls].siz+s[s[x].rs].siz;
}
void insert(int &x,int &y,int l,int r,int p)
{
y=++tot;
if(l==r)
{
s[y].siz=s[x].siz+1;
return ;
}
int mid=l+r>>1;
if(p<=mid) s[y].rs=s[x].rs,insert(s[x].ls,s[y].ls,l,mid,p);
else s[y].ls=s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,p);
pushup(y);
}
int query(int x,int y,int l,int r,int p)
{
if(l==r) return ref[l];
int mid=l+r>>1;
if(s[s[y].ls].siz-s[s[x].ls].siz>=p) return query(s[x].ls,s[y].ls,l,mid,p);
return query(s[x].rs,s[y].rs,mid+1,r,p-s[s[y].ls].siz+s[s[x].ls].siz);
}
int main()
{
n=readin(),m=readin();
int i,a,b,c;
for(i=1;i<=n;i++) v[i].num=readin(),v[i].org=i;
sort(v+1,v+n+1,cmp1);
ref[0]=-1<<30;
for(i=1;i<=n;i++)
{
if(v[i].num>ref[nm]) ref[++nm]=v[i].num;
v[i].num=nm;
}
sort(v+1,v+n+1,cmp2);
for(i=1;i<=n;i++)
insert(root[i-1],root[i],1,nm,v[i].num);
for(i=1;i<=m;i++)
{
a=readin(),b=readin(),c=readin();
printf("%d\n",query(root[a-1],root[b],1,nm,c));
}
return 0;
}

【POJ2104】【HDU2665】K-th Number 主席树的更多相关文章

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

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

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

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

  3. poj2104 K-th Number区间第k小值 主席树

    原来主席树就是可持久化线段树啊,刚知道,,, 作为一道裸题,还是必A的,然而一开始偷懒不写离散化跪了N多遍,后来在缪大的帮助下发现了这个问题,遂A之 ——又是这种破问题,实在不想说自己了 把n个数看成 ...

  4. POJ2104 K-th Number[主席树]【学习笔记】

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 51440   Accepted: 17594 Ca ...

  5. [poj2104] K-th Number (主席树)

    主席树 Description You are working for Macrohard company in data structures department. After failing y ...

  6. 主席树:POJ2104 K-th Number (主席树模板题)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 44952   Accepted: 14951 Ca ...

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

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

  8. 【poj2104】K-th Number 主席树

    题目描述 You are working for Macrohard company in data structures department. After failing your previou ...

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

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

随机推荐

  1. TextureView+SurfaceTexture+OpenGL ES来播放视频(一)

    引自:http://www.ithao123.cn/content-8733143.html 最近发现视频直播类应用层出不穷,比如233手游直播,蓝鲸直播,微录客等等什么的,连android界大神老罗 ...

  2. xcconfig 文件配置文件 问题

    与公司 QA 聊天,已不止一次被吐槽说移动端从开发环境转到生产环境时,还要靠修改代码来配置对应的环境参数.她认为,从 App 转测试之后,就不应该再修改代码,可以把所有的环境配置都整合到配置文件中,这 ...

  3. MaterialWidgetLibrary 学习

    studio项目地址:https://github.com/keithellis/MaterialWidget 修改后的eclipse项目地址: 修改后的eclipse项目 Demo地址: activ ...

  4. jsp导入外部样式

    在博客园遇到一位朋友,她将我的代码下载下去,运行的时候,jsp页面的样式不存在,不会显示出来. 这里就将我之前写的SpringSpringmvcMybatis做一些修改. jdk1.8 加入了两个ja ...

  5. AS-->如何更高效的使用 Gradle, 快速build apk

    版权声明:欢迎转载,转载请注明出处;http://blog.csdn.net/angcyo 看本文之前,推荐先看我之前写的一篇文章: 传送门 日前Android Stuido 已经更新到 2.0.0 ...

  6. css div inline 与 span 区别

    不是说用了display:lnline就变内联原素 和span有区别更奇怪的是ff里面执行就没区别 <span style="">xxx</span> &l ...

  7. 看unix高级编程时遇到apue.h找不到的问题

    最近学习 Unix 环境高级编程这本书,第一个例子就碰到了问题,下面是解决办法. 一开始看到这本书,刚翻了几页,就觉得对味.按照书中的代码做练习时,编译代码文件提示fatal error: apue. ...

  8. n皇后问题<dfs>

    n皇后问题指的是: n*n的国际象棋棋盘上摆放n个皇后,使其不能互相攻击, 即任意两个皇后都不能处于同一行.同一列或同一斜线上, 问有多少种摆法. 和一般n皇后问题不同的是,现在棋盘上有可能已经放了一 ...

  9. nginx的RTMP协议服务器

    nginx的RTMP协议服务器 by ahuner 通过以下的配置,可以使nginx接收RTMP流,并在web上播放实时视频. 1.openssl安装 nginx需要http_ssl_module模块 ...

  10. js中:Date.utc()方法与getTime()方法返回值不相等的原因

    // Date.UTC() 方法接受的参数同日期构造函数接受最多参数时一样,返回从1970-1-1 00:00:00 UTC到指定日期的的毫秒数. var utcDate = Date.UTC(201 ...