首页 技术 正文
技术 2022年11月18日
0 收藏 629 点赞 4,336 浏览 1753 个字

poj2104

题意:给出n个数,有m次查询,每次查询要你找出 l 到 r 中第 k 大的数;

思路:划分树模板题

划分树(poj2104)

上述图片展现了查询时如何往下递推的过程

其中ly表示 [sl,l) 中有多少个数进入了左子树,num[ceng][r]表示[sl,r]中有多少个数进入了左子树,total表示[l,r]中有多少个数进入了左子树。

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
int s[][];
int st[];//排序后的数组
int num[][];//第i层前j个数有几个进入了左子树
void bt(int ceng,int l,int r){
if(l==r)//递归到l,r相等时
return;
int mid=(l+r)/;
int sum1=mid-l+;
for(int i=l;i<=r;i++){//计算该有多少个与中间值相等的数可以进入左子树
if(s[ceng][i]<st[mid])
sum1--;
}
int cnt1=,cnt2=;
for(int i=l;i<=r;i++){
if(i==l){
num[ceng][i]=;
}
else{
num[ceng][i]=num[ceng][i-];
} if(s[ceng][i]<st[mid]||s[ceng][i]==st[mid]&&sum1>){//如果当前数字小于中间数或者当前数等于中间数并且当前进入左子树并与中间数相等的数的数量小于限制数量时
int k1=l+cnt1++;
//printf("qqqq%d %d %d\n",ceng,cnt1,k1);
s[ceng+][k1]=s[ceng][i];
num[ceng][i]++;
if(s[ceng][i]==st[mid])//如果相等,则与中间数相等的数可以进入的位置又少了一个
sum1--;
}
else{//进入右子树
int k2=mid+cnt2++;
s[ceng+][k2]=s[ceng][i];
//printf("qqqq%d %d %d\n",ceng,cnt2,k2);
}
}
bt(ceng+,l,mid);//递归建树
bt(ceng+,mid+,r);
}
int query(int ceng,int sl,int sr,int l,int r,int k){
//printf("www%d %d %d\n",ceng,sl,sr);
if(sl==sr){//递归到叶子节点
//printf("qq%d %d %d\n",ceng,sl,s[ceng][sl]);
return s[ceng][sl];
}
int ly;
if(l==sl)
ly=;//ly代表该段的l前面有多少个数进入了左子树
else
ly=num[ceng][l-];
int total=num[ceng][r]-ly;//l到r之间有多少个数进入了左子树
if(total>=k){//该区间有大于k个数进入了左子树 ,则第k大的数一定在左子树里面
return query(ceng+,sl,(sl+sr)>>,sl+ly,sl+num[ceng][r]-,k);
//l=sl+ly;新的左范围等于边界sl+l前面的数进入左子树的个数
//r=sl+num[ceng][r]-1;新的右范围等于边界sl+前r个数中进入左子树的个数
} //为什么r!=sl+ly + k因为虽然连续,但不是有序的
else{
int lr=l-sl-ly+((sl+sr)>>)+;//新的左范围等于l前面的数的总数减去前面数进入左子树的个数加上右子数的开始位置
return query(ceng+,((sl+sr)>>)+,sr,lr,lr+r-l-total,k-total);
//新的右范围等于新的左范围加上l到r之间数的个数减去l和r之间的数进入左子树的个数
}}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&s[][i]);
st[i]=s[][i];
}
sort(st+,st+n+);
bt(,,n);
while(m--){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",query(,,n,l,r,k));
}
return ;
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,091
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,568
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,416
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,189
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,825
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,908