解题报告:P3834 【模板】可持久化线段树 2(主席树)详解
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
即可得到L
到R
之间的个数: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(主席树)详解相关推荐
- 学习笔记:可持久化线段树(主席树):静态 + 动态
学习笔记:可持久化线段树(主席树):静态 + 动态 前置知识: 线段树.线段树分享可以看:@秦淮岸.@ZYzzz.@妄想の岚がそこに 树状数组.\(BIT\)分享可以看:@T-Sherlock.Chi ...
- 【洛谷】P3919 【模板】可持久化线段树(主席树)
题目 传送门:QWQ 分析 主席树的模板,囤着 代码 #include <bits/stdc++.h> using namespace std; const int N=1000010; ...
- 可持久化线段树【主席树】可持久化并查集【主席树+并查集】
笼统的主席树原理 众所周知, 主席树是可以持久化的, 换言之你能知道你所维护信息的所有历史状态. 主席树是这样做的: 1. 首先建一颗朴素的线段树,代表初始状态 (下图黑色) , 也就是第0次操作后的 ...
- 可持久化线段树(主席树)【舰娘系列】【自编题】
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=60083619 向大(hei)佬(e)势力学(di ...
- 【bzoj3524】【Poi2014】【Couriers】可持久化线段树(主席树)水题
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=62485671 向大(hei)佬(e)势力学(di ...
- 【牛客 - 157C】PH试纸(前缀和,或权值线段树,主席树)
题干: 链接:https://ac.nowcoder.com/acm/contest/157/C 来源:牛客网 题目描述 PH试纸,是一种检测酸碱度的试纸,试纸红色为酸性,蓝色为碱性. HtBest有 ...
- SPOJ - DQUERY D-query(莫队/线段树+离线/主席树)
题目链接:点击查看 题目大意:给出一个由n个数组成的序列,再给出m次查询,每次查询区间[l,r]中有多少个不同的数 题目分析:莫队模板题,直接套板子就好了 有点意思的是函数返回值为布尔类型,然后没有r ...
- BZOj #4771. 七彩树(主席树+dfn序+lca)
BZOj #4771. 七彩树 description solution code description 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色, ...
- 2019.03.25 bzoj4539: [Hnoi2016]树(主席树+倍增)
传送门 题意:给一棵大树,令一棵模板树与这棵树相同,然后进行mmm次操作,每次选择模板树中的一个节点aaa和大树中一个节点bbb,把aaa这棵子树接在bbb上面,节点编号顺序跟aaa中的编号顺序相同. ...
- 洛谷P4216 [SCOI2015]情报传递(树剖+主席树)
传送门 我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间 那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$ 这个只要用主席树上树就可以解决了,顺便用树 ...
最新文章
- 2.innodb后台线程
- 决策树—ID3(源码解析)
- 核能力将定手机浏览器HTML5之争成败
- Ansible8:Playbook循环【转】
- Redis入门之Redis安装、配置及常用指令
- 用IDM快速下载百度云文件
- office2007每次打开都配置进度_解决Office2007每次启动时出现配置进度的问题
- 计算机输入法知识讲解,第一讲计算机基础知识及微软拼音输入法
- 2022年最新WordPress主题更新列表(2022年5月28日)
- Android Debug Bridge(安卓调试桥) tools
- 1.3 基于协同过滤的电影推荐案例
- Linux系统文件加密与解密应用
- 你需要立即停止的9个习惯! 2012-03-11 10:01:41
- python 和vba在财务上_Excel,VBA太烦!PowerBI太贵!可以用Python处理公司财务数据并实现可视化吗?...
- nextjs 基于 isomorphic-unfetch 封装自己的请求库
- _access()函数的使用
- 如何通过检测微芯片操作来对抗硬件木马
- 服装实体店运营需要的所有软件,合集在此!(建议收藏)实体店运营 实体店运营干货 实体店运营全流程所需系统推荐
- 树莓派之更改开机画面
- e智团队实验室项目-第一周-神经网络的学习