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. Oozie的安装过程

    依赖CDH5,JDK和关系数据库 集群规划 主机名   IP                      Ooize节点 CHD1    XX.XX.XX.XX  oozie server,oozie ...

  2. UVA10305 拓扑序

    题意:给出多个任务,以及一系列任务的关系表示某个任务必须在某个任务前完成,问一个合理的任务完成顺序 拓扑序的裸题,一开始用大白书的写法,后来发现并不好用,就换了BFS又A了一遍. 原: #includ ...

  3. [原创]cocos2d-x研习录-第一阶 背景介绍 之 cocos2d家族史

    Cocos2D是一个2D开源游戏引擎,它最早是由Ricardo Quesada(阿根廷人,社区简称Riq)和他的朋友们用Python开发的,用于开发2D游戏和基于2D图形的任何应用.最早引擎的名字源自 ...

  4. Unity摄像机

    把相机做为人物的子对象,就可以制作: 1.第1人称摄像机:把摄像机摆在眼睛前面 2.第3人称摄像机:把摄像机摆在人后上面 Clear Flags: http://www.haogongju.net/a ...

  5. 利用KMeans聚类进行航空公司客户价值分析

    准确的客户分类的结果是企业优化营销资源的重要依据,本文利用了航空公司的部分数据,利用Kmeans聚类方法,对航空公司的客户进行了分类,来识别出不同的客户群体,从来发现有用的客户,从而对不同价值的客户类 ...

  6. c# 图片XML序列化与反序列化

    var xmlDoc = new XmlDocument(); xmlDoc.Load(@"C:\Users\*\Desktop\*.xml"); ].ChildNodes[]; ...

  7. Struts2中s:set标签和s:if标签小结

    1.  s:set标签 格式:<s:set name="" value="" scope=””/> 说明:把jsp页面中的一个值,以name存储起来 ...

  8. dubbo Linux 解决:nc: command not found

    出现该情况有两种可能: (1)没有配置nc命令的环境变量: (2)该系统没有安装nc命令: 我查看了一下在/usr/bin目录中并没有nc命令,所以我可以认为出现该情况的原因是第二种情况 下载安装 下 ...

  9. 简述oracle视图

    1.视图的概述 视图其实就是一条查询sql语句,用于显示一个或多个表或其他视图中的相关数据.视图将一个查询的结果作为一个表来使用,因此视图可以被看作是存储的查询或一个虚拟表.视图来源于表,所有对视图数 ...

  10. systemd的原理和适用方法

    systemd的原理: https://www.linux.com/learn/tutorials/527639-managing-services-on-linux-with-systemd htt ...