区间第K小——可持久化线段树模板
概念
分析
sort + unique
进行离散化操作;然后以离散化后的元素作为底层(接下来大概就是用线段树按顺序记录每个数字出现的次数)。l..r
需要查询两个版本:ver[l-1]
与ver[r]
,同步查询两棵树,并对查询到的内容相减便是l..r
中该范围内的数据(以数字出现字数为关键词)。相当于线段树的前缀和。#include<bits/stdc++.h>
using namespace std; const int maxn = 2e5 + ;
int n, m, size_disc; //size_disc是离散化之后的长度
int n_init[maxn], n_disc[maxn]; //原数组 离散化后的数组
int rt[maxn], lc[maxn << ], rc[maxn << ], sum[maxn << ]; //rt:不同版本的根节点 lc/rc: 左儿子、右儿子(公用) sum: 和(公用)
int node_cnt, pnt_disc; //node总计数, pnt_disc: A中数字对应B中的值 void build(int& last_node, int l, int r)
{
last_node = ++ node_cnt;
sum[last_node] = ;
if(l == r) return;
int mid = (l + r) >> ;
build(lc[last_node], l, mid);
build(rc[last_node], mid+, r);
} int modify(int pre_rt, int l, int r)
{
int new_rt = ++node_cnt;
lc[new_rt] = lc[pre_rt];
rc[new_rt] = rc[pre_rt];
sum[new_rt] = sum[pre_rt] + ; int mid = (l + r) >> ;
if(l == r) return new_rt;
if(mid >= pnt_disc) lc[new_rt] = modify(lc[new_rt], l, mid);
else rc[new_rt] = modify(rc[new_rt], mid+, r);
return new_rt;
} int query(int rt1, int rt2, int k, int l, int r)
{
//printf("rt1:%d rt2:%d k:%d l:%d r:%d ", rt1, rt2, k, l, r);
if(l == r) return l;
int mid = (l + r) >> ;
int tmp = sum[lc[rt2]] - sum[lc[rt1]];
//int tmp=sum[lc[rt2]]-sum[lc[rt1]]; //printf("tmp:%d k:%d\n", tmp, k); int ans;
if(tmp >= k) ans = query(lc[rt1], lc[rt2], k, l, mid);
else ans = query(rc[rt1], rc[rt2], k-tmp, mid+, r);
return ans;
} void print_debug()
{
printf("node_cnt: %d\n", node_cnt);
for(int i = ;i <= node_cnt;i++)
printf("%d lc:%d rc:%d sum:%d\n", i, lc[i], rc[i], sum[i]);
} int main()
{
scanf("%d%d", &n, &m);
for(int i = ;i <= n;i++)
{
scanf("%d", &n_init[i]);
n_disc[i] = n_init[i];
}
sort(n_disc+, n_disc+n+); //先排序再进行离散化
size_disc = unique(n_disc+, n_disc+n+) - (n_disc+); node_cnt = ;
build(rt[], , size_disc);
for(int i = ;i <= n;i++)
{
pnt_disc = lower_bound(n_disc+, n_disc+size_disc+, n_init[i]) - n_disc; //改了1
rt[i] = modify(rt[i-], , size_disc); //只在上一个版本的基础上修改
} for(int i = ;i <m;i++)
{
int l, r, k;
scanf("%d%d%d", &l, &r, &k);l--;
int ans = query(rt[l], rt[r], k, , size_disc);
printf("%d\n", n_disc[ans]);
}
}
其中,遍历1~n建立n棵线段树的过程如下:
其中第i棵是建立在i-1棵的基础上,加上它们的n相同,结构也完全相同,两颗线段树相减就是这两个操作之间的变化值。
参考链接:
区间第K小——可持久化线段树模板的更多相关文章
- POJ- 2104 hdu 2665 (区间第k小 可持久化线段树)
可持久化线段树 也叫函数式线段树也叫主席树,其主要思想是充分利用历史信息,共用空间 http://blog.sina.com.cn/s/blog_4a0c4e5d0101c8fr.html 这个博客总 ...
- [POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]
可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include &l ...
- 区间第k大问题 权值线段树 hdu 5249
先说下权值线段树的概念吧 权值平均树 就是指区间维护值为这个区间内点出现次数和的线段树 用这个加权线段树 解决第k大问题就很方便了 int query(int l,int r,int rt,int k ...
- 序列内第k小查询(线段树)
最近请教了一下大佬怎么求序列内第k大查询,自己又捣鼓了一下,虽然还没有懂得区间第k大查询,不过姑且做一个记录先吧 因为每个元素大小可能很大而元素之间不连续,所以我们先离散化处理一下,程序中的ori[ ...
- hdu 4417 区间内比h小的数 线段树
题意求区间内比h小的数的个数 将所有的询问离线读入之后,按H从小到大排序.然后对于所有的结点也按从小到大排序,然后根据查询的H,将比H小的点加入到线段树,然后就是一个区间和. 2015-07-27:专 ...
- HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- SPOJ Meteors - 可持久化线段树 - 二分法
Byteotian Interstellar Union (BIU) has recently discovered a new planet in a nearby galaxy. The plan ...
- 洛谷P3834【模板】可持久化线段树 1(主席树)
题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...
- [DP][SA][可持久化线段树]黑红兔
源自 xyz32768 菜鸡的 FJ 省冬令营模拟赛题 原题 CF1063F Statement 给定一个长度为 \(n\) 的字符串 \(s\),仅包含小写英文字母 要从中从左往右选出若干段不相交的 ...
随机推荐
- 使用Dreamweaver制作简单网站(二)
继续上周没完成的 一.新建iframe.css 1.点击文件-选择新建-css 2.ctrl+s保存为iframe.css 在style文件夹下. 3.回到main.html 右键选择-附加样式表,选 ...
- javascript当中类型转换,typeof的用法
1)类型转换,typeof的用法 例 3.1.1 <HTML><head> <meta http-equiv="content-type" co ...
- Spark学习一:Spark概述
1.1 什么是Spark Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎. 一站式管理大数据的所有场景(批处理,流处理,sql) spark不涉及到数据的存储,只 ...
- c++:论如何成功把自己搞懵【二叉树特辑①】(不定期更新)
并不正经的前言 以前我这个小白看OI的书,老觉得有些东西很高端(看不懂的自然就很高端[滑稽]):什么栈啊,位运算啊,二叉树啊.有些东西我学了之后也很迷糊(真的不是因为傻?),做题的时候总是可以把自己搞 ...
- 20190728-Python爬取视频&切割视频&视频加水印
1.视频爬取 1.下载视频的源码如下: import os import requests from bs4 import BeautifulSoup import threading from bj ...
- python3.7 lxml4.2.5 etree xpath 的使用
#2019年10月14日11:08:49 from lxml import html etree = html.etree html = etree.HTML(response_dl.content) ...
- CSP-S2019「Symphony」
NOTICE:如觉得本文有什么错误或不妥之处,欢迎评论区以及私信交流,反对乱喷,如有一些让人不爽的评论或人身攻击,带来的后果本人一律不负责 准备工作 Day-inf~Day-3 000 every d ...
- selenium 12306模拟登陆
代码应用场景 :基于第三方打码网站模拟登陆12306 验证码识别 基于第三方平台超级鹰识别 超级鹰官网:http://www.chaojiying.com/user/ 超级鹰使用流程: 注册 登陆(用 ...
- MySQL cmd操作
1.开启关闭服务 net start mysql net stio mysql 2.登陆 在CMD命令窗口敲入命令 mysql -hlocalhost -uroot -p 后按回车(注意这里的&quo ...
- vue 之this.$router.push、replace、go的区别
一.this.$router.push 说明:跳转到指定URL,向history栈添加一个新的记录,点击后退会返回至上一个页面 使用: this.$router.push('/index') this ...