poj 2104 K-th Number(主席树 视频)
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(主席树 视频)的更多相关文章
- 【POJ 2104】 K-th Number 主席树模板题
达神主席树讲解传送门:http://blog.csdn.net/dad3zz/article/details/50638026 2016-02-23:真的是模板题诶,主席树模板水过.今天新校网不好,没 ...
- 静态区间第k大(主席树)
POJ 2104为例(主席树入门题) 思想: 可持久化线段树,也叫作函数式线段树,也叫主席树(高大上). 可持久化数据结构(Persistent data structure):利用函数式编程的思想使 ...
- poj 2104 K-th Number 主席树+超级详细解释
poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...
- poj2104 k-th number 主席树入门讲解
poj2104 k-th number 主席树入门讲解 定义:主席树是一种可持久化的线段树 又叫函数式线段树 刚开始学是不是觉得很蒙逼啊 其实我也是 主席树说简单了 就是 保留你每一步操作完成之后 ...
- POJ 2104 K-th Number 主席树(区间第k大)
题目链接: http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MSMemory Limit: 65536K 问题描述 You ar ...
- POJ 2104:K-th Number(主席树静态区间k大)
题目大意:对于一个序列,每次询问区间[l,r]的第k大树. 分析: 主席树模板题 program kthtree; type point=record l,r,s:longint; end; var ...
- POJ 2104 K-th Number ( 求取区间 K 大值 || 主席树 || 离线线段树)
题意 : 给出一个含有 N 个数的序列,然后有 M 次问询,每次问询包含 ( L, R, K ) 要求你给出 L 到 R 这个区间的第 K 大是几 分析 : 求取区间 K 大值是个经典的问题,可以使用 ...
- SPOJ MKTHNUM & POJ 2104 - K-th Number - [主席树模板题]
题目链接:http://poj.org/problem?id=2104 Description You are working for Macrohard company in data struct ...
- Poj 2104 K-th Number(主席树&&整体二分)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Case Time Limit: 2000MS Description You are wor ...
随机推荐
- [AMPPZ 2013]Bytehattan
先把题目链接贴在这里喵~ http://main.edu.pl/en/archive/amppz/2013/baj 话说真是一道让我严重怀疑我的智商的好题目, 话说此题第一感觉.嗯?似乎离线做做就可以 ...
- 黑马程序员——JAVA基础之包,权限
------- android培训.java培训.期待与您交流! ---------- 包(package) 对类文件进行分类管理. 给类提供多层命名空间. 写在程序文件的第一行. 类名的全称的是:包 ...
- javaweb在线预览
需要工具: 1.openoffice 将word.excel.ppt.txt等文件转换为pdf文件 2.SWFTool 将pdf转换为swf文件 3.flexPaper是一个开源轻量级的在浏览器上显示 ...
- Redis GEO ,GEOHASH,Spatial_index
https://matt.sh/redis-geo http://antirez.com/latest/0 http://invece.org/ https://github.com/davidmot ...
- 使用substring和split方法从字符串中抽取一组清单
提取前: '这是一个句子.这是一个句子,包含了一列清单: 樱桃, 橙子, 桔子, 苹果, 香蕉.这是清单内容.'; 提取后: ["樱桃", " 橙子", &qu ...
- 请让页面中的一个元素(10px*10px)围绕坐标(200, 300) 做圆周运动
<!DOCTYPE html> <html> <head> <title>Making things move</title> <me ...
- Mongo导出数据文件导致错误 Got signal: 6 (Aborted)解决方法
一哥们要导出一个数据表的数据,结果导出一半,硬盘不够用,卡死了, 然后重启主机,导致mongo启动后进程自动死掉, 报错如下. Mon Oct 28 10:39:02.270 [initandlist ...
- alpha预乘
将(r,g,b,a)变为(r*a,g*a,b*a,a)的操作称为alpha预乘. 对于alpha预乘的图片,应使用(One,OneMinusSrcAlpha)进行混合. 使用alpha预乘方式混合出来 ...
- angular.element方法汇总以及AngularJS 动态添加元素和删除元素
addClass()-为每个匹配的元素添加指定的样式类名after()-在匹配元素集合中的每个元素后面插入参数所指定的内容,作为其兄弟节点append()-在每个匹配元素里面的末尾处插入参数内容att ...
- Redis持久化机制和恢复机制
Redis持久化方式有两种: (1)RDB 对内存中数据库状态进行快照 (2)AOF 把每条写命令都写入文件,类似mysql的binlog日志 RDB 将Redis在内存中的数据库状态保存到磁盘里面, ...