参考:优秀的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;的更多相关文章

  1. 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 ...

  2. 主席树模板poj 2104

    资料1:http://blog.csdn.net/regina8023/article/details/41910615 资料2:模板来源:http://www.cnblogs.com/lidaxin ...

  3. POJ 2104&HDU 2665 Kth number(主席树入门+离散化)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 50247   Accepted: 17101 Ca ...

  4. poj 2104 K-th Number 主席树+超级详细解释

    poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...

  5. 主席树 【权值线段树】 && 例题K-th Number POJ - 2104

    一.主席树与权值线段树区别 主席树是由许多权值线段树构成,单独的权值线段树只能解决寻找整个区间第k大/小值问题(什么叫整个区间,比如你对区间[1,8]建立一颗对应权值线段树,那么你不能询问区间[2,5 ...

  6. BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7143  Solved: 2968[Su ...

  7. POJ 2104 K-th Number(主席树——附讲解)

    Description You are working for Macrohard company in data structures department. After failing your ...

  8. Luogu Dynamic Ranking (带修改的主席树)

    题目大意: 网址:https://www.luogu.org/problemnew/show/2617 给定一个序列a[1].a[2].....a[N],完成M个操作,操作有两种: [1]Q i j ...

  9. BZOJ2141排队——树状数组套权值线段树(带修改的主席树)

    题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...

  10. POJ 2104 && POJ 2761 (静态区间第k大,主席树)

    查询区间第K大,而且没有修改. 使用划分树是可以做的. 作为主席树的入门题,感觉太神奇了,Orz /* *********************************************** ...

随机推荐

  1. 关于 '<a[^>]+href=["\'](.*?)["\']' 的解释

    '<a[^>]+href=["\'](.*?)["\']' [] 表示匹配其中的任意字符 ^>  表示除了 > 的字符 ["\'] 表示" ...

  2. maven 下载 安装 环境配置

    电脑系统:win10  64位   idea 2019    Java 1.8 1.链接地址,我一般都找官网 http://maven.apache.org/download.cgi 截图:注意mav ...

  3. SpringMVC学习笔记之---深入使用

    SpringMVC深入使用 (一)基于XML配置的使用 (1)配置 1.SpringMVC基础配置 2.XML配置Controller,HandlerMapping组件映射 3.XML配置ViewRe ...

  4. Canvas动画(PC端 移动端)

    Canvas动画(PC端 移动端) 一,介绍与需求 1.1,介绍 canvas是HTML5中新增一个HTML5标签与操作canvas的javascript API,它可以实现在网页中完成动态的2D与3 ...

  5. 【Java例题】8.1手工编写加法器的可视化程序

    1. 手工编写加法器的可视化程序. 一个Frame窗体容器,布局为null,三个TextField组件,一个Button组件. Button组件上添加ActionEvent事件监听器ActionLis ...

  6. appcan IDE 无法 请求数据

    我们4月27号从4.0.1升级到4.0.2后,IDE本地预览get请求不到数据.但是在线打包安装到手机又是正常的. 先下载 "uexXmlHttpMgr.rar",下载链接:htt ...

  7. go 学习笔记之有意思的变量和不安分的常量

    首先希望学习 Go 语言的爱好者至少拥有其他语言的编程经验,如果是完全零基础的小白用户,本教程可能并不适合阅读或尝试阅读看看,系列笔记的目标是站在其他语言的角度学习新的语言,理解 Go 语言,进而写出 ...

  8. 《白帽子讲web安全》——吴瀚清 阅读笔记

    浏览器安全 同源策略:浏览器的同源策略限制了不同来源的“document”或脚本,对当前的“document”读取或设置某些属性.是浏览器安全的基础,即限制不同域的网址脚本交互     <scr ...

  9. ‎Cocos2d-x 学习笔记(21) ScrollView (CCScrollView)

    1. 简介 CCScrollView.cpp文件内的滚动视图ScrollView直接继承了Layer+ActionTweenDelegate. 滚动视图能在屏幕区域内,用户通过触摸拖动屏幕,实现大于屏 ...

  10. 多线程之NSThread

    关于多线程会有一系列如下:多线程之概念解析 多线程之pthread, NSThread, NSOperation, GCD 多线程之NSThread 多线程之NSOperation 多线程之GCD一, ...