【 静态区间 kth 】 第 k 小数
传送门
题意
给定一个长度为的整数序列,下标为,
个操作,每次给定,表示询问下标为的区间内第小的数
数据范围
题解
值域很大,建立权值线段树,权值线段树要求离散化后的值之间的大小关系不发生改变进行离散化后通过二分查找找到离散化后的下标值
- 线段树的左右儿子不再通过堆的存储实现,通过左右指针指向左右儿子
- 其中当前的值不通过线段树结点的属性体现,体现在各个函数的参数之中
- 每次的插入操作都时,都只会修改左右指针中可能发生变化的子树,一共次,所以每次插入在树上都只有一条链会被修改
- 按照原序列的下标一个一个的插入,插入时即第一个版本
- 询问下标中的数的个数的时候利用前缀和的思想做第个版本的和第个版本的差即可
- 每次查询如果当前左区间差的个数就递归左子树,否则递归右子树并将
- 当查询到边界时,即当前值即第个值,其表示的时原值离散化后的值,即其在离散化后的数中的下标
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
const int N=1e5+10;
struct node{
int l,r;
int cnt;
}tr[N*4+N*17];
int a[N];
int root[N],id;
vector<int>dis;
int find(int x){
return lower_bound(dis.begin(),dis.end(),x)-dis.begin();
}
// 返回的是当前区间的指针
int build(int l,int r){
int now=++id;
if(l==r) return now;
int mid=l+r>>1;
tr[now].l=build(l,mid);// 递归获得右子树指针
tr[now].r=build(mid+1,r);
return now;
}
// pre 表示上一版本的指针,l,r表示离散化后的值域范围,x表示当前插入节点离散化后的值
int insert(int pre,int l,int r,int x){
int now=++id;
tr[now]=tr[pre];
if(l==r){
tr[now].cnt++;
return now;
}
int mid=l+r>>1;
// 只修改左指针
if(x<=mid) tr[now].l=insert(tr[pre].l,l,mid,x);
// 只修改右指针
else tr[now].r=insert(tr[pre].r,mid+1,r,x);
tr[now].cnt=tr[tr[now].l].cnt+tr[tr[now].r].cnt;
return now; // 回溯插入后的节点指针
}
int query(int aft,int pre,int l,int r,int k){
if(l==r) return r;
int cnt=tr[tr[aft].l].cnt-tr[tr[pre].l].cnt;
int mid=l+r>>1;
if(k<=cnt) return query(tr[aft].l,tr[pre].l,l,mid,k);
else return query(tr[aft].r,tr[pre].r,mid+1,r,k-cnt);
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
rep(i,1,n) {
scanf("%d",&a[i]);
dis.push_back(a[i]);
}
sort(dis.begin(),dis.end());
dis.erase(unique(dis.begin(),dis.end()),dis.end());
root[0]=build(0,dis.size()-1); // 只建树,不插入节点
rep(i,1,n)
root[i]=insert(root[i-1],0,dis.size()-1,find(a[i]));
while(m--){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",dis[query(root[r],root[l-1],0,dis.size()-1,k)]);
}
return 0;
}
本文作者:Hyx'
本文链接:https://www.cnblogs.com/hhyx/p/13934021.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)