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+7; const int INF=0x3f3f3f3f;struct node {int l,r; //l,r分别指向左右孩子,但由于历史的错乱,二者的值未必有规律 int size; //当前历史版本里,该节点中所包含的元素个数//p.s. 在最后一个历史版本里,size即为总元素个数n }tr[N*20]; //主席树的初始状态为一“空架子” //每次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+1,t+1+m,x)-t; } int q; //q个询问int build(int l,int r) {int rt=tot++;tr[rt].size=0;if(l==r) return rt;int mid=(l+r)>>1;tr[rt].l=build(l,mid);tr[rt].r=build(mid+1,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)>>1;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+1,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)>>1;if(diff>=k) return query(tr[ql].l,tr[qr].l,l,mid,k);else return query(tr[ql].r,tr[qr].r,mid+1,r,k-diff); } int main() {while(~scanf("%d%d",&n,&q)){for(int i=1;i<=n;i++)scanf("%d",&a[i]),t[i]=a[i];sort(t+1,t+1+n);m=unique(t+1,t+1+n)-t-1;m++,t[m]=INF;tot=0;root[0]=build(1,m); //初始化一个空线段树for(int i=1;i<=n;i++){int order=pos(a[i]);root[i]=updata(root[i-1],1,m,order,1);//每次在上一次已完成的基础上新增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-1],root[r],1,m,k)]); } } }
转载于:https://www.cnblogs.com/Just--Do--It/p/6523238.html
poj 2104: K-th Number 【主席树】相关推荐
- 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(主席树)
题目链接:点击查看 题目大意:给出一个数列,然后是m次查询,每次查询闭区间[l,r]内第K大的数 题目分析:裸的主席树,暑假集训第三周的时候就听说过了这个数据结构,不过当时太懒了,而且那些主席树的问题 ...
- K-th Closest Distance HDU - 6621(第k小绝对值+主席树+二分)
You have an array: a1, a2, , an and you must answer for some queries. For each query, you are given ...
- 【HDU - 2665】Kth number(区间第K大,主席树,模板)
题干: Give you a sequence and ask you the kth big number of a inteval. Input The first line is the num ...
- 主席树学习小结(POJ 2104)
在高中的时候就听到过主席树了,感觉非常高端,在寒假的时候 winter homework中有一题是查找区间第K大的树,当时就开始百度这种网上的博客,发现主席树看不懂,因为那个root[i],还有tx[ ...
- 主席树的各类模板(区间第k大数【动,静】,区间不同数的个数,区间=k的个数)...
取板粗 好东西来的 1.(HDOJ2665)http://acm.hdu.edu.cn/showproblem.php?pid=2665 (POJ2104)http://poj.org/probl ...
- HDU 4417 Super Mario(线段树离线处理/主席树)
Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in ...
- SPOJ COT Count on a tree(主席树+倍增lca)
思路:这个题其实就是树上的第k小,主席树的本质还是类似于前缀和一样的结构,所以是完全相同的,所以我们在树上也可以用同样的方法,我们对于每一个节点进行建树,然后和普通的树上相同,ab之间的距离是等于 r ...
最新文章
- Hadoop HA 深度解析
- python的def函数_Python 学习之 def 函数
- 理解JavaScript继承(二)
- source insight 常用设置及快捷键
- AI知识点(1)--激活函数
- Ubuntu 修复windows启动项
- (实例篇)php 使用redis锁限制并发访问类示例
- C语言二维数组指针(指向二维数组的指针)详解
- 微信JSSDK使用签名算法
- 战神网络 战神引擎 手游研究院 获取该区补丁失败 如何解决
- python2代码转换python3(2018新)
- 253:丛林中的路——最小生成树Prim
- 余柳:国际视角下城市交通碳中和策略与路径研究
- BZOJ1455罗马游戏
- CSS—表单的样式设置
- pcl聚类----欧式聚类分割方法
- 学好英语网html首页制作,网页 英语
- 同态加密库Seal库的安装(win11+VS2022)
- 【JVM】四、JVM优化-GC调优
- java高级面试视频,持续更新~
热门文章
- 删除作业计划出错(DELETE语句与 REFERENCE约束FK_subplan_job_id冲突。)
- 什么是HTTP Headers?
- IDEA+selenium+TestNG+java+git+maven+jenkins实现Web UI自动化集成
- 利用Caffe训练模型(solver、deploy、train_val) + python如何使用已训练模型
- NotePad++列编辑
- 论jquery与vuejs结合时的部分问题
- Hibernate学习之hibernate状态
- OC中的自动引用计数
- 软件开发者的最佳实践
- html右键禁用和web页面中添加加入qq群的方式