poj 2104: K-th Number 【主席树】
学习了一下主席树,感觉具体算法思路不大好讲。。
大概是先建个空线段树,然后类似于递推,每一个都在前一个“历史版本”的基础上建立一个新的“历史版本”,每个历史版本只需占用树高个空间(好神奇!)
查询时这道题是通过“历史版本”间作差解决
*另外提一下,在建立“历史版本”的过程中,是“新建”,而不是“更新”,是先copy过来原有的,再按个人需求改成自己的,所产生的一个新的“历史版本”
希望注释能有帮助
//吐槽一下,本人看kuangbin模板看得好费劲,一方面不习惯用lson[],rson[]数组搞线段树,另一方面他的update query函数都是用二分写的,看半天没理解。。。
以下是按个人习惯加了注释的代码
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#define M 100000+5
using namespace std; const int N=1e5+;
const int INF=0x3f3f3f3f; struct node
{
int l,r; //l,r分别指向左右孩子,但由于历史的错乱,二者的值未必有规律
int size; //当前历史版本里,该节点中所包含的元素个数
//p.s. 在最后一个历史版本里,size即为总元素个数n
}tr[N*];
//主席树的初始状态为一“空架子”
//每次updata都在前一“历史版本”基础上新建h个结点,共updata n次,产生了n个历史版本,每个版本占用空间为h*sizeof(one node)
int tot; //结点建立顺序|所赋标号 int n; //共n个数
int a[N]; //读入数组
int root[N];//记录a[]中每一个数对应各“历史版本”在主席树中的根结点标号
int m; //t[]中元素个数
int t[N]; //离散数组
int pos(int x)
{
return lower_bound(t+,t++m,x)-t;
}
int q; //q个询问 int build(int l,int r)
{
int rt=tot++;
tr[rt].size=;
if(l==r) return rt;
int mid=(l+r)>>;
tr[rt].l=build(l,mid);
tr[rt].r=build(mid+,r);
return rt;
} // pre_node:最近一历史,[l,r]当前所更新到的包含x的区间
// x此次更新的“终点”
// 沿途要增加的“权值”
// p.s. 1<=l<=r<=m
int updata(int pre_node,int l,int r,int x,int v)
{
int rt=tot++; //rt为新结点的标号
tr[rt]=tr[pre_node]; //先拷贝原指向当前区间的结点
tr[rt].size+=v;
// 在函数不断向下深入过程中,更新node.size
if(l==r) return rt;
int mid=(l+r)>>;
if(x<=mid) tr[rt].l=updata(tr[pre_node].l,l,mid,x,v);
else tr[rt].r=updata(tr[pre_node].r,mid+,r,x,v);
return rt;
// 在函数逐步return过程中,更新node.l|r
} // ql,qr反应的是在a[]中的下标,对应着更新到该下标时的“历史版本”
// l,r反应的是在t[]中的下标
int query(int ql,int qr,int l,int r,int k)
{
if(l==r) return l;
int diff=tr[tr[qr].l].size-tr[tr[ql].l].size;//在更新到ql位置和更新到qr位置时两个“历史版本”下左孩子的size之差
// p.s. size的大小反应较小数的多少
int mid=(l+r)>>;
if(diff>=k) return query(tr[ql].l,tr[qr].l,l,mid,k);
else return query(tr[ql].r,tr[qr].r,mid+,r,k-diff);
}
int main()
{
while(~scanf("%d%d",&n,&q))
{
for(int i=;i<=n;i++)
scanf("%d",&a[i]),t[i]=a[i];
sort(t+,t++n);
m=unique(t+,t++n)-t-;
m++,t[m]=INF;
tot=;
root[]=build(,m); //初始化一个空线段树
for(int i=;i<=n;i++)
{
int order=pos(a[i]);
root[i]=updata(root[i-],,m,order,);
//每次在上一次已完成的基础上新增h个结点
//从根 逐步新建结点到 a[i]在线段树上所对应的位置
//在这个逐步新建结点的过程中,要新建的结点的l,r始终满足l<=m<=r
//这些结点每一个的size都在pre_node的基础上+1
}
while(q--)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",t[query(root[l-],root[r],,m,k)]);
}
}
}
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 题意: 给你一些数,让你求一个区间内,第k大的数是多少. 题解: 主席树第一题,看的qsc视频写的,戳戳戳 学到了unique函数,他的作用是:把相邻的重复的放到后面,返回值是 ...
- Poj 2104 K-th Number(主席树&&整体二分)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Case Time Limit: 2000MS Description You are wor ...
随机推荐
- SQL利用Case When Then Else End 多条件判断
Select Case When a is not null then a When b is not null then b When c is not null then c When d is ...
- 判断逻辑 先判断协议字段返回,再判断业务返回,最后判断交易状态 API密钥
[微信支付]微信小程序支付开发者文档 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_1 协议规则 商户接入微信支付, ...
- RESTful_基础知识
目录 目录 前言 RESTful REST原则 REST的Web原则 分层系统原则 RESTful的实现 SOA 面向服务的体系结构 RPC样式 Web服务 RPC的实现过程 SOAP 简单对象访问协 ...
- EXE的32位或64位判断
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC> dumpbin /headers "Program.exe" ...
- hdu6228Tree
Problem Description Consider a un-rooted tree T which is not the biological significance of tree or ...
- TensorFlow学习笔记1-入门
TensorFlow学习笔记1-入门 作者: YunYuan *** 写在前面 本笔记是我学习TensorFlow官方文档中文版的读书笔记,由于尚未搭建好Github的个人博客的评论功能,故尚不方便与 ...
- Gradient Vanishing Problem in Deep Learning
在所有依靠Gradient Descent和Backpropagation算法来学习的Neural Network中,普遍都会存在Gradient Vanishing Problem.Backprop ...
- 爬虫(十一)—— XPath总结
目录 XPath总结 一.何为XPath 二.XPath语法 1.语法 2.实例 三.XPath轴 1.XPath轴语法 2.XPath轴实例 四.XPath运算符 XPath总结 一.何为XPath ...
- python包的补充
1.包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间 2.常见目录结构 import os 2 os.makedirs('glance/api') 3 os.makedirs('gl ...
- anaconda安装教程、管理虚拟环境
原文链接:https://blog.csdn.net/ITLearnHall/article/details/81708148 另可参看文章:https://www.cnblogs.com/jonin ...