K-th Number

题意:

给你一些数,让你求一个区间内,第k大的数是多少。

题解:

主席树第一题,看的qsc视频写的,戳戳戳

学到了unique函数,他的作用是:把相邻的重复的放到后面,返回值是放后面的第一个的迭代器。 故使用之前要排序,之后在用erase删除后面重复的,便可达到去重的目的,之后就可以离散化了。

代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1e5+6;
int n,m,cnt,root[maxn],a[maxn],x,y,k;
struct node{int l,r,sum;}T[maxn*40];
vector<int>v;
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)
{
T[++cnt]=T[y],T[cnt].sum++,x=cnt;
if (l==r) return;
int mid=(l+r)/2;
if (mid>=pos)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)/2;
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+1,r,T[x].r,T[y].r,k-sum);
}
int main()
{
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());
for(int i=1;i<=n;i++)update(1,n,root[i],root[i-1],getid(a[i]));
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&k);
printf("%d\n",v[query(1,n,root[x-1],root[y],k)-1]);
}
}

另一种写法:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=100001;
struct Node{
int ls,rs;
int cnt;
}tr[maxn*20];
int cur,rt[maxn];
void init(){
cur=0;
}
inline void push_up(int o){
tr[o].cnt=tr[tr[o].ls].cnt+tr[tr[o].rs].cnt;
}
int build(int l,int r){
int k=cur++;
if (l==r) {
tr[k].cnt=0;
return k;
}
int mid=(l+r)>>1;
tr[k].ls=build(l,mid);
tr[k].rs=build(mid+1,r);
push_up(k);
return k;
}
int update(int o,int l,int r,int pos,int val){
int k=cur++;
tr[k]=tr[o];
if (l==pos&&r==pos){
tr[k].cnt+=val;
return k;
}
int mid=(l+r)>>1;
if (pos<=mid) tr[k].ls=update(tr[o].ls,l,mid,pos,val);
else tr[k].rs=update(tr[o].rs,mid+1,r,pos,val);
push_up(k);
return k;
}
int query(int l,int r,int o,int v,int kth){
if (l==r) return l;
int mid=(l+r)>>1;
int res=tr[tr[v].ls].cnt-tr[tr[o].ls].cnt;
if (kth<=res) return query(l,mid,tr[o].ls,tr[v].ls,kth);
else return query(mid+1,r,tr[o].rs,tr[v].rs,kth-res);
}
int b[maxn];
int sortb[maxn];
int main()
{
int n,m;
int T;
while (~scanf("%d%d",&n,&m)){
init();
for (int i=1;i<=n;i++){
scanf("%d",&b[i]);
sortb[i]=b[i];
}
sort(sortb+1,sortb+1+n);
int cnt=1;
for (int i=2;i<=n;i++){
if (sortb[i]!=sortb[cnt]){
sortb[++cnt]=sortb[i];
}
}
rt[0]=build(1,cnt);
for (int i=1;i<=n;i++){
int p=lower_bound(sortb+1,sortb+cnt+1,b[i])-sortb;
rt[i]=update(rt[i-1],1,cnt,p,1);
}
for (int i=0;i<m;i++){
int a,b,k;
scanf("%d%d%d",&a,&b,&k);
int idx=query(1,cnt,rt[a-1],rt[b],k);
printf("%d\n",sortb[idx]);
}
}
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大)

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

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

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

  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 Time Limit: 20000MS Memory Limit: 65536K Case Time Limit: 2000MS Description You are wor ...

随机推荐

  1. PHP防止页面刷新、重复提交数据

    PHP防止页面刷新.重复提交数据 (2011-12-09 16:52:45) 转载▼ 标签: it 分类: php技术相关 闲来无事看了一下php session ,又在网上看了防止页面刷新重复提交数 ...

  2. Linux系统编程@进程管理(二)

    1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...

  3. java的nio之:java的nio系列教程之buffer的概念

    一:java的nio的buffer==>Java NIO中的Buffer用于和NIO通道Channel进行交互.==>数据是从通道channel读入缓冲区buffer,从缓冲区buffer ...

  4. 新手教程之:循环网络和LSTM指南 (A Beginner’s Guide to Recurrent Networks and LSTMs)

    新手教程之:循环网络和LSTM指南 (A Beginner’s Guide to Recurrent Networks and LSTMs) 本文翻译自:http://deeplearning4j.o ...

  5. mysql 1449 : The user specified as a definer ('root'@'%') does not exist ,mysql 赋给用户权限 grant all privileges on

    mysql 1449 : The user specified as a definer ('root'@'%') does not exist 解决方法 遇到了 SQLException: acce ...

  6. Axure轮播图

    制作步骤如下: 1.新建一个动态面板,并添加几个动态面板状态(tab) 2.在所建的几个动态面板状态中添加要显示的每个广告的图片和相对应的代表第几个广告的数字. 3.添加页面交互事件.添加事件是在页面 ...

  7. OpenJudge计算概论-求一元二次方程的根【含复数根的计算、浮点数与0的大小比较】

    /*====================================================================== 求一元二次方程的根 总时间限制: 1000ms 内存限 ...

  8. comet基于HTTP长连接技术(java即时通信,推送技术详解)

    服务器推送技术的基础思想是将浏览器主动查询信息改为服务器主动发送信息,服务器发送一批数据,浏览器显示消息,同时保证与服务器的连接,当服务器需要再一次的发送数据,浏览器显示数据并保持连接. comet基 ...

  9. C转义字符

    C语言输出特殊字符 C语言转义字符意义大体同于前面的C#转义字符,这里列出用c语言,输出%d.\n等特殊字符的方法. #include <stdio.h> int main() { pri ...

  10. MyBatis java and MySql local variables

    <insert id="create" parameterType="models.entities.CategoryEntity"> set @c ...