【洛谷 P3834】 可持久化线段树1(主席树)
主席树=可持久化权值线段树。
如果你不会可持久化线段树,请右转
如果你不会权值线段树,请自行脑补,就是线段树维护值域里有多少个数出现。
可持久化线段树是支持查询历史版本的。
我们对每个数都进行一次基于上个版本的单点修改操作,这样每个版本就是维护的前\(p\)个数,这个权值显然满足可减性。
所以,要查询区间\([l,r]\)的第\(k\)大时,我们就用第\(r\)个版本减去第\(l-1\)个版本,我们就得到了一颗\([l,r]\)的权值线段树,然后跑第\(k\)小就简单了:
如果左儿子有大于等于\(k\)个数,就继续去左儿子找第\(k\)小,否则设左儿子的值为\(lcnt\),去右儿子找第\(k-lcnt\)小。
#include <cstdio>
#include <algorithm>
using std::sort;
#define re register
inline int read(){
int s = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); }
return s * w;
}
const int MAXN = 200010;
const int MAXM = 200010;
const int MAXMLOGN = 4000010;
struct SegTree{
int lc, rc, cnt;
SegTree(){ lc = rc = cnt = 0; }
}t[MAXMLOGN];
int root[MAXM];
int a[MAXN], c[MAXN], d[MAXN];
int n, m, tot, num;
int build(int l, int r){
int id = ++tot;
if(l == r) return id;
int mid = (l + r) >> 1;
t[id].lc = build(l, mid);
t[id].rc = build(mid + 1, r);
return id;
}
int insert(int now, int l, int r, int x){
int id = ++tot;
t[id] = t[now];
if(l == r){ ++t[id].cnt; return id; }
int mid = (l + r) >> 1;
if(x <= mid) t[id].lc = insert(t[now].lc, l, mid, x);
else t[id].rc = insert(t[now].rc, mid + 1, r, x);
t[id].cnt = t[t[id].lc].cnt + t[t[id].rc].cnt;
return id;
}
int ask(int p, int q, int l, int r, int k){
if(l == r) return l;
int mid = (l + r) >> 1;
int L = t[t[p].lc].cnt - t[t[q].lc].cnt;
if(k <= L) return ask(t[p].lc, t[q].lc, l, mid, k);
else return ask(t[p].rc, t[q].rc, mid + 1, r, k - L);
}
struct divide{
int id, val;
bool operator < (const divide A) const{
return val < A.val;
}
}b[MAXN];
int l, r, k;
int main(){
n = read(); m = read();
for(re int i = 1; i <= n; ++i){
b[i].val = a[i] = read();
b[i].id = i;
}
sort(b + 1, b + n + 1);
b[0].val = -2147483646;
for(int i = 1; i <= n; ++i)
if(b[i].val != b[i - 1].val){
c[b[i].id] = ++num;
d[num] = b[i].val;
}
else c[b[i].id] = num;
root[0] = build(1, num);
for(int i = 1; i <= n; ++i)
root[i] = insert(root[i - 1], 1, num, c[i]);
for(re int i = 1; i <= m; ++i){
l = read(); r = read(); k = read();
printf("%d\n", d[ask(root[r], root[l - 1], 1, num, k)]);
}
getchar();
return 0;
}
【洛谷 P3834】 可持久化线段树1(主席树)的更多相关文章
- 洛谷P3834 可持久化线段树(主席树)模板
题目:https://www.luogu.org/problemnew/show/P3834 无法忍受了,我要写主席树! 解决区间第 k 大查询问题,可以用主席树,像前缀和一样建立 n 棵前缀区间的权 ...
- 洛谷 [P3834] 可持久化线段树(主席树)
主席树可以存储线段树的历史状态,空间消耗很大,一般开45n即可 #include <iostream> #include <cstdio> #include <cstri ...
- 洛谷 P3919 可持久化线段树 题解
题面 这题好水的说~很明显就是主席树的大板子 然而我交了3遍才调完所有的BUG,开好足够的数组,卡掉大大的常数: 针对与每次操作,change()会创建新节点,而ask()虽然也会更新左右儿子的节点编 ...
- 洛谷P2633 Count on a tree(主席树,倍增LCA)
洛谷题目传送门 题目大意 就是给你一棵树,每个点都有点权,每次任意询问两点间路径上点权第k小的值(强制在线). 思路分析 第k小......又是主席树了.但这次变成树了,无法直接维护前缀和. 又是树上 ...
- 洛谷P2633 Count on a tree(主席树,倍增LCA,树上差分)
洛谷题目传送门 题目大意 就是给你一棵树,每个点都有点权,每次任意询问两点间路径上点权第k小的值(强制在线). 思路分析 第k小......又是主席树了.但这次变成树了,无法直接维护前缀和. 又是树上 ...
- 2018.07.01洛谷P2617 Dynamic Rankings(带修主席树)
P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i ...
- 【洛谷4587】 [FJOI2016]神秘数(主席树)
传送门 BZOJ 然而是权限题 洛谷 Solution 发现题目给出的一些规律,emm,如果我们新凑出来的一个数,那么后面一个数一定是\(sum+1\). 于是就可以主席树随便维护了! 代码实现 #i ...
- 洛谷P2633/bzoj2588 Count on a tree (主席树)
洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...
- 【洛谷 P3168】 [CQOI2015]任务查询系统(主席树)
题目链接 被自己的sb错误调到自闭.. 主席树的进阶应用. 把\(P_i\)离散化一下,得到每个\(P_i\)的排名,然后建一棵维护\(m\)个位置的主席树,每个结点记录区间总和和正在进行的任务数. ...
- 【洛谷 P3899】 [湖南集训]谈笑风生 (主席树)
题目链接 容易发现\(a,b,c\)肯定是在一条直链上的. 定义\(size(u)\)表示以\(u\)为根的子树大小(不包括\(u\)) 分两种情况, 1.\(b\)是\(a\)的祖先,对答案的贡献是 ...
随机推荐
- cgi、fastcgi、php-cgi、php-fpm的关系
1. CGI CGI全称是"公共网关接口"(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行"交谈"的一种工具,其 ...
- redis学习资料汇总
redis学习资料汇总 2017年01月07日 22:10:37 阅读数:281 转载:http://blog.csdn.net/wtyvhreal/article/details/50427627 ...
- 常用js方法合集
var Default = { init: function () { }, addCookie: function (name,data) { var expdate = new Date(); / ...
- php 使用GD库压缩图片,添加文字图片水印
先上一个工具类,提供了压缩,添加文字.图片水印等方法: image.class.php <?php class Image { private $info; private $image; pu ...
- C#文件重命名的代码
C#中没有重命名的方法,自己写了一个方法,来处理文件的重命名. /// <summary> /// 重命名文件夹内的所有子文件夹 /// </summary> /// < ...
- Django入门与实战
第1章 介绍课程目标及学习内容 1-1 课程介绍: 第2章 课前准备 2-1 课前准备: 第3章 开发环境搭建 3-1 开发环境搭建: 第4章 创建项目及应用 4-1 创建项目,并了解项目目录下的部分 ...
- Tuxedo 介绍与安装
Tuxedo 介绍与安装(一) Tuxedo介绍 ...
- zabbix从入门到精通
第1章 zabbix监控 1.1 为什么要监控 在需要的时刻,提前提醒我们服务器出问题了 当出问题之后,可以找到问题的根源 网站/服务器 的可用性 1.1.1 网站可用性 在软件系统的高可靠性(也 ...
- COJ 2192: Wells弹键盘 (dp)
2192: Wells弹键盘 Description Wells十分羡慕和佩服那些会弹钢琴的人比如子浩君,然而Wells只会弹键盘…… Wells的键盘只有10个键,从1,2,3,……,9,0,如下图 ...
- 为DEV C++/CodeBlock配置gdb调试遇到的问题
DEV C++和CodeBlock都只是一个IDE,不能编译调试,需要自己配置MINGW和gdb调试 1.MINGW 在这下载mingw-get-setup.exe安装即可. https://sour ...