[hdu2665]Kth number(划分树求区间第k大)
解题关键:划分树模板题。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int MAXN=;
int tree[][MAXN],sorted[MAXN],toleft[][MAXN];
void build(int l,int r,int dep){
if(l==r)return;
int mid=(l+r)>>;
int same=mid-l+;//表示等于中间值而且被分入左边的个数
for(int i=l;i<=r;i++)
if(tree[dep][i]<sorted[mid])
same--;
int lpos=l,rpos=mid+;
for(int i=l;i<=r;i++){
if(tree[dep][i]<sorted[mid])//比中间的数小,分入左边
tree[dep+][lpos++]=tree[dep][i];
else if(tree[dep][i]==sorted[mid]&&same>){
tree[dep+][lpos++]=tree[dep][i];
same--;
}
else tree[dep+][rpos++]=tree[dep][i];
toleft[dep][i]=toleft[dep][l-]+lpos-l;//从1到i放左边的个数
}
build(l,mid,dep+);
build(mid+,r,dep+);
} //查询区间第k大的数,[L,R]是大区间,[l,r]是要查询的小区间
int query(int L,int R,int dep,int l,int r,int k){
if(l==r)return tree[dep][l];
int mid=(L+R)>>;
int cnt=toleft[dep][r]-toleft[dep][l-];//[l,r]中位于左边的个数
if(cnt>=k){
//L+要查询的区间前被放在左边的个数
int newl=L+toleft[dep][l-]-toleft[dep][L-];
//左端点加上查询区间会被放在左边的个数
int newr=newl+cnt-;
return query(L,mid,dep+,newl,newr,k);
}
else{
int newr=r+toleft[dep][R]-toleft[dep][r];//懂了
int newl=newr-(r-l-cnt);
return query(mid+,R,dep+,newl,newr,k-cnt);
}
} int main(){
int T;
int n,m;
int s,t,k;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
memset(tree,,sizeof tree);//这个必须
for(int i=;i<=n;i++){
scanf("%d",&tree[][i]);
sorted[i]=tree[][i];
}
sort(sorted+,sorted+n+);
build(,n,);
while(m--){
scanf("%d%d%d",&s,&t,&k);
printf("%d\n",query(,n,,s,t,k));
}
}
return ;
}
[hdu2665]Kth number(划分树求区间第k大)的更多相关文章
- HDU 3473 Minimum Sum (划分树求区间第k大带求和)(转)
题意:在区间中找一个数,求出该区间每个数与这个数距离的总和,使其最小 找的数字是中位数(若是偶数个,则中间随便哪个都可)接着找到该区间比此数大的数的总和 区间中位数可以使用划分树,然后在其中记录:每层 ...
- K-th Number 线段树的区间第K大
http://poj.org/problem?id=2104 由于这题的时间限制不紧,所以用线段树水一水. 每个节点保存的是一个数组. 就是对应区间排好序的数组. 建树的时间复杂度需要nlogn 然后 ...
- [csu/coj 1080]划分树求区间前k大数和
题意:从某个区间内最多选择k个数,使得和最大 思路:首先题目给定的数有负数,如果区间前k大出现负数,那么负数不选和更大,于是对于所有最优选择,负数不会出现,所以用0取代负数,问题便转化为区间的前k大数 ...
- HDOJ题目4417 Super Mario(划分树求区间比k小的个数+二分)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- [poj2104]kth-number(归并树求区间第k大)
复杂度:$O(nlog^3n)$ #include<cstdio> #include<cstring> #include<algorithm> #include&l ...
- poj 2104 主席树(区间第k大)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 44940 Accepted: 14946 Ca ...
- POJ2761---Feed the dogs (Treap求区间第k大)
题意 就是求区间第k大,区间 不互相包含. 尝试用treap解决一下 第k大的问题. #include <set> #include <map> #include <cm ...
- hdu 2665 Kth number(划分树模板)
http://acm.hdu.edu.cn/showproblem.php?pid=2665 [ poj 2104 2761 ] 改变一下输入就可以过 http://poj.org/problem? ...
- POJ2104 k-th number 划分树
又是不带修改的区间第k大,这次用的是一个不同的方法,划分树,划分树感觉上是模拟了快速排序的过程,依照pivot不断地往下划分,然后每一层多存一个toleft[i]数组,就可以知道在这一层里从0到i里有 ...
随机推荐
- [LeetCode系列]爬梯问题的递归解法转换为迭代解法
有一个n阶的梯子, 你每次只能爬1阶或2阶, 请问共有多少种登顶的爬法?(正好爬完n阶, 不能多也不能少) 本题最优解是直接套用菲波那切数列即可(因为菲波那切数列的第n个元素正好等于第n-1个元素和第 ...
- php mysql 字符集(三) (转)
http://bbs.csdn.net/topics/390097514 gbk页面插入数据到utf8表,然后取出到gbk页面 首先, 这个set names x等价于SET character_se ...
- 面试常考知识点——Java(JVM,JDK,JRE)
1. 什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? 答:(1)Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Java虚拟机执行的字节码文件. ...
- 设计WEB数据库(学习)
设计WEB数据库 1.考虑建模的实际对象 为现实世界的实体和关系建立模型 在上面情况下考虑建表呢? 答:如果有一组属于同一类型的数据,就可以根据这些数据创建表 2.避免保存冗余数据 原因:a.空间的浪 ...
- Protobuff java 文件生成命令
protoc.exe -I./proto文件目录 --java_out=java文件目录 proto文件基于文件目录的全路径 protoc.exe -I./protoFolder --java_out ...
- 在Mac下配置php开发环境:Apache+php+MySql (卡在 给mysql 设置不了账号密码)
https://my.oschina.net/joanfen/blog/171109#OSC_h4_3 cmd 进入mysql的方法
- SpringMVC之八:基于SpringMVC拦截器和注解实现controller中访问权限控制
SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法. preHandle在业务处理器 ...
- python 将html实体转回去
参考资料: http://www.360doc.com/content/17/0620/16/44530822_664927373.shtml https://blog.csdn.net/guzhou ...
- Linux命令之hostname - 显示或设置主机名
我使用过的Linux命令之hostname - 显示或设置主机名 本文链接:http://codingstandards.iteye.com/blog/804648 (转载请注明出处) 用途说明 ...
- @Retention 注解的作用
注解@Retention可以用来修饰注解,是注解的注解,称为元注解.Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚 ...