P3834 【模板】可持久化线段树 2(主席树)

题解 P3834 【【模板】可持久化线段树 2(主席树)】

1)静态求第k大数

可持久化线段树,不能用堆的方法存子结点了,所以用指针l表示左儿子r表示右儿子

可持久化线段树难以处理区间修改,因为很难处理懒惰标记,除非使用永久化标记线段树

新版本其他的都不变,只把新的点替换,其他的性质例如左右儿子是谁不变,所以每新加入一个数,也就是到了新版本,就完成与一次新老版本的迭代(tr[q] = tr[p] q是新版本p是老版本)

线段树维护的是整个值域。
在数值上建立一个线段树,维护cnt表示每个数值的区间上一共有几个数。

线段树和平衡树都是二叉树,所以我们需要做二分的时候可以考虑能否在树里做二分。

我们首先考虑[1,R]这个区间的个数。很明显我们可以直接用第R个版本即可。
但是我们要求的是[L,R]这个区间,有两个限制。所以我们利用类似前缀和的思想,用第R个版本个数cnt1减去第L-1个版本cnt2
即可得到LR之间的个数:cnt1-cnt2

每次都是个上一个版本比较
l指的是左儿子,不是左边界

由于数据范围达到了1e9
所以需要离散化

//线段树维护的是数值#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>using namespace std;
const int N = 500007, M = 10007, INF = 0x3f3f3f3f;int n, m;
int idx;
int a[N];
int root[N];
vector<int> nums;
struct Tree{int l, r;int cnt;//表示的是这个值域区间一共有多少个数
}tr[N * 4 + N * 17];//log(1e5) ≈ 17int find(int x){return lower_bound(nums.begin(), nums.end(), x) - nums.begin();
}int build(int l, int r){int p = ++ idx;if(l == r)return p;int mid = l + r >> 1;tr[p].l = build(l, mid);tr[p].r = build(mid + 1, r);return p;
}int insert(int p, int l, int r, int x){//开始把n个数插入(迭代新版本)int q = ++ idx;tr[q] = tr[p];//新老版本交接if(l == r){tr[q].cnt ++ ;return q;}int mid = l + r >> 1;if(x <= mid)tr[q].l = insert(tr[p].l, l, mid, x);else tr[q].r = insert(tr[p].r, mid + 1, r, x);tr[q].cnt = tr[tr[q].l].cnt + tr[tr[q].r].cnt ;return q;
}int query(int q, int p, int l, int r, int k){if(l == r)return r;int mid = l + r >> 1;int cnt = tr[tr[q].l].cnt - tr[tr[p].l].cnt;if(k <= cnt)return query(tr[q].l, tr[p].l, l, mid, k);else return query(tr[q].r, tr[p].r, mid + 1, r, k - cnt);//这里注意往右区间找的时候第k大已经变成了k-cnt大了
}int main(){scanf("%d%d", &n, &m);for(int i = 1;i <= n; ++ i){scanf("%d", &a[i]);nums.push_back(a[i]);}sort(nums.begin(), nums.end());nums.erase(unique(nums.begin(), nums.end()), nums.end());//第一个版本root[0] = build(0, nums.size() - 1);//新版本是由旧版本继承过来的for(int i = 1;i <= n; ++ i)root[i] = insert(root[i - 1], 0, nums.size() - 1, find(a[i]));while(m -- ){int l, r, k;scanf("%d%d%d", &l, &r, &k);printf("%d\n", nums[query(root[r], root[l - 1], 0, nums.size() - 1, k)]);}return 0;
}

解题报告:P3834 【模板】可持久化线段树 2(主席树)详解相关推荐

  1. 学习笔记:可持久化线段树(主席树):静态 + 动态

    学习笔记:可持久化线段树(主席树):静态 + 动态 前置知识: 线段树.线段树分享可以看:@秦淮岸.@ZYzzz.@妄想の岚がそこに 树状数组.\(BIT\)分享可以看:@T-Sherlock.Chi ...

  2. 【洛谷】P3919 【模板】可持久化线段树(主席树)

    题目 传送门:QWQ 分析 主席树的模板,囤着 代码 #include <bits/stdc++.h> using namespace std; const int N=1000010; ...

  3. 可持久化线段树【主席树】可持久化并查集【主席树+并查集】

    笼统的主席树原理 众所周知, 主席树是可以持久化的, 换言之你能知道你所维护信息的所有历史状态. 主席树是这样做的: 1. 首先建一颗朴素的线段树,代表初始状态 (下图黑色) , 也就是第0次操作后的 ...

  4. 可持久化线段树(主席树)【舰娘系列】【自编题】

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=60083619 向大(hei)佬(e)势力学(di ...

  5. 【bzoj3524】【Poi2014】【Couriers】可持久化线段树(主席树)水题

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=62485671 向大(hei)佬(e)势力学(di ...

  6. 【牛客 - 157C】PH试纸(前缀和,或权值线段树,主席树)

    题干: 链接:https://ac.nowcoder.com/acm/contest/157/C 来源:牛客网 题目描述 PH试纸,是一种检测酸碱度的试纸,试纸红色为酸性,蓝色为碱性. HtBest有 ...

  7. SPOJ - DQUERY D-query(莫队/线段树+离线/主席树)

    题目链接:点击查看 题目大意:给出一个由n个数组成的序列,再给出m次查询,每次查询区间[l,r]中有多少个不同的数 题目分析:莫队模板题,直接套板子就好了 有点意思的是函数返回值为布尔类型,然后没有r ...

  8. BZOj #4771. 七彩树(主席树+dfn序+lca)

    BZOj #4771. 七彩树 description solution code description 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色, ...

  9. 2019.03.25 bzoj4539: [Hnoi2016]树(主席树+倍增)

    传送门 题意:给一棵大树,令一棵模板树与这棵树相同,然后进行mmm次操作,每次选择模板树中的一个节点aaa和大树中一个节点bbb,把aaa这棵子树接在bbb上面,节点编号顺序跟aaa中的编号顺序相同. ...

  10. 洛谷P4216 [SCOI2015]情报传递(树剖+主席树)

    传送门 我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间 那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$ 这个只要用主席树上树就可以解决了,顺便用树 ...

最新文章

  1. 2.innodb后台线程
  2. 决策树—ID3(源码解析)
  3. 核能力将定手机浏览器HTML5之争成败
  4. Ansible8:Playbook循环【转】
  5. Redis入门之Redis安装、配置及常用指令
  6. 用IDM快速下载百度云文件
  7. office2007每次打开都配置进度_解决Office2007每次启动时出现配置进度的问题
  8. 计算机输入法知识讲解,第一讲计算机基础知识及微软拼音输入法
  9. 2022年最新WordPress主题更新列表(2022年5月28日)
  10. Android Debug Bridge(安卓调试桥) tools
  11. 1.3 基于协同过滤的电影推荐案例
  12. Linux系统文件加密与解密应用
  13. 你需要立即停止的9个习惯! 2012-03-11 10:01:41
  14. python 和vba在财务上_Excel,VBA太烦!PowerBI太贵!可以用Python处理公司财务数据并实现可视化吗?...
  15. nextjs 基于 isomorphic-unfetch 封装自己的请求库
  16. _access()函数的使用
  17. 如何通过检测微芯片操作来对抗硬件木马
  18. 服装实体店运营需要的所有软件,合集在此!(建议收藏)实体店运营 实体店运营干货 实体店运营全流程所需系统推荐
  19. 树莓派之更改开机画面
  20. e智团队实验室项目-第一周-神经网络的学习

热门文章

  1. 如何用 OpenCV、Python 和深度学习实现面部识别?
  2. 红外线可程序化?遥控器Motedem控制自家居住环境
  3. 关系型数据库-三范式
  4. Clever Answers in Codewar(Javascript 持续更新)
  5. java模拟验证码生成
  6. Python 1 数据类型的操作
  7. SQLite管理工具绿色
  8. 保险业尚不能完全发挥CRM优势 需强化
  9. Postfix(一):CentOS 下安装postfix
  10. 如何在GNOME中添加自己的菜单项