poj2104

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

思路:划分树模板题

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

其中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 ;
}

划分树(poj2104)的更多相关文章

  1. 划分树 poj2104 hdu5249

    KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  2. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

  3. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

  4. poj2104&&poj2761 (主席树&&划分树)主席树静态区间第k大模板

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

  5. 初学划分树,小见解之!POJ-2104/HDU-2665

    划分树 本来是学主席树的,可怜我等巨弱观群巨博客难解fotle主席的思想精髓.于是学了一下划分树,嗯,花了一下午时间理解build(其实自己模拟一遍就通了),我很难理解为什么划分树会看不懂而能学会主席 ...

  6. hdu2665 && poj2104划分树

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

  7. poj2104 线段树 划分树

    学习:http://www.cnblogs.com/pony1993/archive/2012/07/17/2594544.html 划分树的build: 划分树是分层构建的,在构建的t层时,我们可以 ...

  8. POJ2104 k-th number 划分树

    又是不带修改的区间第k大,这次用的是一个不同的方法,划分树,划分树感觉上是模拟了快速排序的过程,依照pivot不断地往下划分,然后每一层多存一个toleft[i]数组,就可以知道在这一层里从0到i里有 ...

  9. poj2104 划分树 区间K大 在线 无修改

    博主sbit....对于高级数据结构深感无力,然后这些东西在OI竟然烂大街了,不搞就整个人都不好了呢. 于是我勇猛的跳进了这个大坑 ——sbit 区间K大的裸题,在线,无修改. 可以用归并树(\(O( ...

随机推荐

  1. .Net 多线程 (1) Task

    多线程是一种有效提高程序工作效率的方法.当然为了效率需要使用更多的cpu,内存等资源. 并发是两个队列交替使用一台咖啡机,并行是两个队列同时使用两台咖啡机,如果串行,一个队列使用一台咖啡机,那么哪怕前 ...

  2. Mysql数据库优化之SQL及索引优化

    1. 如何发现有问题的SQL?  使用mysql慢查询日志对有效率问题的Sql进行监视 (1) show  variables like 'slow_query_log';     查看慢查询日志是否 ...

  3. (转) SpringMVC学习笔记-

    一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 <!--conf ...

  4. Quartz.net定时任务框架的使用

    一:Nuget添加Quartz.net和Topshelf 二:新建HelloJob类继承IJob public class HelloJob : IJob       {            pub ...

  5. 怎样从外网访问内网Sysbase数据库

    外网访问内网Sysbase数据库 本地安装了Sysbase数据库,只能在局域网内访问,怎样从外网也能访问本地Sysbase数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Sys ...

  6. LeetCode #001# Two Sum(js描述)

    索引 思路1:暴力搜索 思路2:聪明一点的搜索 思路3:利用HashMap巧解 问题描述:https://leetcode.com/problems/two-sum/ 思路1:暴力搜索 一个很自然的想 ...

  7. python爬虫——绕开杂乱无章的代码和堵住请求的302异常(2)

    淘宝那次抓包,居然发现不了要抓的url位置,三星中... 不过不怕,不就是没法快点分析出包嘛,下次用phantomJS硬杠,或者有时间慢慢分析也好. 今天挑战一个稍微好爬的网站:狗搬家(误) 打开后台 ...

  8. 使用JS调用手机本地摄像头或者相册图片识别二维码/条形码

    接着昨天的需求,不过这次不依赖微信,使用纯js唤醒手机本地摄像头或者选择手机相册图片,识别其中的二维码或者是条形码.昨天,我使用微信扫一扫识别,效果超棒的.不过如果依赖微信的话,又怎么实现呢,这里介绍 ...

  9. 调用微信的扫一扫功能详解说明---(java 排坑版)

    最近碰到了这么一个需求,说是在前端页面调用手机本地的相机,扫描二维码这么一个需求,对于我一个后端来说, 这实在是难,难于上青天,但是决不能说一个不字.我说可以使用微信的扫码工具吗,这样可以方便一点,. ...

  10. android中SELINUX规则分析和语法简介【转】

    本文转载自:https://blog.csdn.net/LoongEmbedded/article/details/62430039 1. SELINUX是可以理解为一种Android上面的安全机制, ...