【洛谷 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\)的祖先,对答案的贡献是 ...
随机推荐
- Android Google Maps 开始
由于工作需要,最近对Android的各大地图进行了试用. 其中有Google地图,百度地图,高德地图,还有开源的OSM. 在使用Google地图的时候,官网流程写的非常清楚,但是其中也遇到一些问题.这 ...
- 第八篇Python基本数据类型之列表、元组与字典
列表 写在最前,必须要会的:append(),extend(),insert(),索引,切片,循环 list 是一个类,是个对象 列表用 方括号[]括起来的,[]内以逗号分割每个元素,列表中的元素可 ...
- python中socket、socketio、flask-socketio、WebSocket的区别与联系
socket.socketio.flask-socketio.WebSocket的区别与联系 socket 是通信的基础,并不是一个协议,Socket是应用层与TCP/IP协议族通信的中间软件抽象层, ...
- ORM选型对比
ORM框架选型 ORM框架选型 jian A YEAR AGO (2017-04-10) orm, database 选型标准:实现O/R mapping,基于promise,支持原生SQL语句,支持 ...
- php+Mysql中网页出现乱码的解决办法详解
$conn = mysql_connect("$host","$user","$password");mysql_query("S ...
- Packet filtering with Linux & NAT
http://www.linuxfocus.org/ChineseGB/May2003/article289.shtml Gateway, Proxy-Arp 和 Ethernet Bridge ? ...
- python practive
定义新的操作指令,并将其组合到一起以便能够做一些有意义的事情,这就是编程工作的核心和灵魂. 计算型思维: 1,强调概念化,而非程序化.计算机科学不是计算机程序.像计算机科学家一样的思考,不只是说要编程 ...
- npm基本使用
常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用. 允许用户将自己编写的包或命令行程序上传到NPM服 ...
- JSP表单提交出现中文乱码的解决方法
1)post方式 在servlet的doGet( ) doPost( ) 中增加以下代码: response.setContentType("text/html;charset=utf- ...
- 【2017.12.22.A】
A 题面: 给一个n个点m条边的无向图,你可以选择一个点作为起点,然后沿着图中的边开始走,走的过程中,同一条边不能经过两次(相反的方向也不行). ...