不修改的主席(HJT)树-HDU2665,POJ-2104;
参考:优秀的B站视频;
和 https://blog.csdn.net/creatorx/article/details/75446472
感觉主席树这个思路是真的优秀,每次在前一次的线段树的基础上建立一颗新的小线段树;所以更新和查询都是要前后两个根节点进行操作;
利用引用,只用修改此次的节点,而不动前一次的线段树;
主席树可用在求区间的第K大的数上:思路是:
我们也可以利用前缀和这个思想来解决建树这个问题,我们只需要建立n颗“前缀”线段树就行,第i树维护[1,i]序列,这样我们处理任意区间l, r时就可以通过处理区间[1,l - 1], [1,r],就行,然后两者的处理结果进行相加相减就行。为什么满足相加减的性质,我们简单分析一下就很容易得出。如果在区间[1,l - 1]中有x个数小于一个数,在[1,r]中有y个数小于那个数,那么在区间[l,r]中就有y - x 个数小于那个数了,这样就很好理解为什么可以相加减了,另外,每颗树的结构都一样,都是一颗叶节点为n个的线段树。
这里还有一个利用vector离散化的操作;
hdu ac的:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
#define pb push_back
const int maxn = ; struct node {
int l,r;
int sum;
}T[maxn*];
int a[maxn],root[maxn];
vector<int>v;
int getid(int x){
return lower_bound(v.begin(),v.end(),x) - v.begin() + ;
}
int n,m,cnt,x,y,k; void init(){
v.clear();
memset(T,,sizeof(T));
cnt = ;
}
void update(int l,int r,int &x,int y,int pos)
{
T[++cnt] = T[y]; T[cnt].sum++; x = cnt;
if(l==r)return;
int mid = (l+r)>>;
if(mid>=pos)
update(l,mid,T[x].l,T[y].l,pos);
else update(mid+,r,T[x].r,T[y].r,pos);
} int query(int l,int r,int x,int y,int pos)
{
if(l==r)return l;
int sum = T[T[y].l].sum - T[T[x].l].sum;
int mid = (l+r)>>;
if(sum >= pos)
return query(l,mid,T[x].l,T[y].l,pos);
else return query(mid+,r,T[x].r,T[y].r,pos - sum);
}
int main(){
int t;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d",&n,&m);
for(int i=; i<=n; i++)
{
scanf("%d", &a[i]);
v.pb(a[i]);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(),v.end()),v.end()); for(int i=; i<=n; i++)
update(,n,root[i],root[i-],getid(a[i]));
for(int i=; i<=m; i++)
{
int le,ri,k;
scanf("%d%d%d", &le,&ri,&k);
printf("%d\n",v[query(,n,root[le-],root[ri],k)-]);
}
}
return ;
}
POJ的
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
#define pb push_back
const int maxn = ; struct node {
int l,r;
int sum;
}T[maxn*];
int a[maxn],root[maxn];
vector<int>v;
int getid(int x){
return lower_bound(v.begin(),v.end(),x) - v.begin() + ;
}
int n,m,cnt,x,y,k; void update(int l,int r,int &x,int y,int pos)
{
T[++cnt] = T[y]; T[cnt].sum++; x = cnt;
if(l==r)return;
int mid = (l+r)>>;
if(mid>=pos)
update(l,mid,T[x].l,T[y].l,pos);
else update(mid+,r,T[x].r,T[y].r,pos);
} int query(int l,int r,int x,int y,int pos)
{
if(l==r)return l;
int sum = T[T[y].l].sum - T[T[x].l].sum;
int mid = (l+r)>>;
if(sum >= pos)
return query(l,mid,T[x].l,T[y].l,pos);
else return query(mid+,r,T[x].r,T[y].r,pos - sum);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=; i<=n; i++)
{
scanf("%d", &a[i]);
v.pb(a[i]);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(),v.end()),v.end()); for(int i=; i<=n; i++)
update(,n,root[i],root[i-],getid(a[i]));
for(int i=; i<=m; i++)
{
int le,ri,k;
scanf("%d%d%d", &le,&ri,&k);
printf("%d\n",v[query(,n,root[le-],root[ri],k)-]);
} return ;
}
不修改的主席(HJT)树-HDU2665,POJ-2104;的更多相关文章
- 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 ...
- 主席树模板poj 2104
资料1:http://blog.csdn.net/regina8023/article/details/41910615 资料2:模板来源:http://www.cnblogs.com/lidaxin ...
- POJ 2104&HDU 2665 Kth number(主席树入门+离散化)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 50247 Accepted: 17101 Ca ...
- poj 2104 K-th Number 主席树+超级详细解释
poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...
- 主席树 【权值线段树】 && 例题K-th Number POJ - 2104
一.主席树与权值线段树区别 主席树是由许多权值线段树构成,单独的权值线段树只能解决寻找整个区间第k大/小值问题(什么叫整个区间,比如你对区间[1,8]建立一颗对应权值线段树,那么你不能询问区间[2,5 ...
- BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7143 Solved: 2968[Su ...
- POJ 2104 K-th Number(主席树——附讲解)
Description You are working for Macrohard company in data structures department. After failing your ...
- Luogu Dynamic Ranking (带修改的主席树)
题目大意: 网址:https://www.luogu.org/problemnew/show/2617 给定一个序列a[1].a[2].....a[N],完成M个操作,操作有两种: [1]Q i j ...
- BZOJ2141排队——树状数组套权值线段树(带修改的主席树)
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...
- POJ 2104 && POJ 2761 (静态区间第k大,主席树)
查询区间第K大,而且没有修改. 使用划分树是可以做的. 作为主席树的入门题,感觉太神奇了,Orz /* *********************************************** ...
随机推荐
- css3系列之详解perspective
perspective 简单来说,就是设置这个属性后,那么,就可以模拟出像我们人看电脑上的显示的元素一样.比如说, perspective:800px 意思就是,我在离屏幕800px 的地方观看这 ...
- IDED中配置SVN没有svn.exe解决办法
首先在idea中配置svn时
- Vector使用方法简单整理
使用vector,需要引用vector库: #include<vector> 首先,创建一个可以容纳int的vector变量——arr: vector<int> arr; 接着 ...
- 如何在logback.xml中自定义动态属性
当使用logback来记录Web应用的日志时,我们通过在logback.xml中配置appender来指定日志输出格式及输出文件路径,这在一台主机或一个文件系统上部署单个实例没有问题,但是如果部署多个 ...
- property修饰关键字
修饰符按作用区分:线程安全相关,内存相关,读写权限相关,set=和get=,是否可为空, class 一.默认值 @property NSArray *dataArray; 默认的是:atomic,s ...
- python之web自动化验证码识别解决方案
验证码识别解决方案 对于web应用程序来讲,处于安全性考虑,在登录的时候,都会设置验证码,验证码的类型种类繁多,有图片中辨别数字字母的,有点击图片中指定的文字的,也有算术计算结果的,再复杂一点就是滑动 ...
- Pycharm2019.2.1永久激活
Pycharm2019.2.1永久激活 Pycharm官网自7月24更新到pycharm2019.2版本后,在短短的一个月内与8月23又带来新版本2019.2.1,不可说更新不快,对于"喜新 ...
- 淘宝自动登录2.0,新增Cookies序列化
前段时间时间为大家讲解了如何使用requests库模拟登录淘宝,而今天我们将对该功能进行丰富.所以我们把之前的那个版本定为1.0,而今天修改的版本定为2.0.版本的地跌意味着功能的升级,那今天的2.0 ...
- 使用Makefile构建Docker
使用Makefile构建Docker 刚开始学习docker命令的时候,很喜欢一个字一个字敲,因为这样会记住命令.后来熟悉了之后,每次想要做一些操作的时候就不得不 重复的输入以前的命令.当切换一个项目 ...
- yolo v2
https://blog.csdn.net/wfei101/article/details/79398563 https://blog.csdn.net/oppo62258801/article/de ...