静态区间第k大(分桶法和平方分割)
POJ 2104为例
思想:
《挑战程序设计竞赛》中介绍的方法。
分桶法:把一排物品或者平面分成桶,每个桶分别维护自己内部的信息,已达到高效计算的目的。
设一共有n个数,每b个分到一个桶里,并对桶内元素进行排序。给定区间,求小于x的数的个数
- 对于完全包含在区间内的桶,直接二分查找满足条件的个数,每个桶处理需要O(logb)的时间。
- 剩余的不完全分布在其他桶的数,逐个查找,每个元素处理需要O(1)的时间。
- 可以看出,应该使桶的个数比桶内元素个数略少一些。
如果b=n−−√,那么这就叫平方分割,查找过程时间复杂度为O(n−−√logn),如果b=nlogn−−−−−√,那么复杂度为O(nlogn−−−−−√),加上最外面的二分,整体时间复杂度为O(nlogn+mn−−√log1.5n)。
代码:
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 1e5+5, b = 1200;
int a[maxn], num[maxn];//[)
vector<int>v[maxn/b];
int main (void)
{
int n, m;scanf("%d%d",&n,&m);
//int b = floor(sqrt(n));
for(int i = 0; i < n; i++){
scanf("%d",&a[i]);
v[i/b].push_back(a[i]);
num[i] = a[i];
}
sort(num, num + n);
for(int i = 0; i <= n/b; i++)
sort(v[i].begin(), v[i].end());
int l, r, mid;
int lo, ro, k, tl, tr;
while(m--){
scanf("%d%d%d",&tl,&tr,&k);
int l = 0, r = n;
while(l < r - 1){
int c = 0;
mid = l + (r - l)/2;
lo = tl -1, ro = tr;
while(lo<ro && lo%b != 0) if(a[lo++] < num[mid]) c++;
while(lo<ro && ro%b != 0 )if(a[--ro] < num[mid]) c++;
for(int i = lo/b; i < ro/b; i++)
c +=lower_bound(v[i].begin(), v[i].end(), num[mid]) - v[i].begin();
if(c <= k-1) l = mid;
else r = mid;
}
printf("%d\n",num[l]);
}
return 0;
}//11000ms
分桶法思想get了,可是这个跑的也真的是有点慢。。。
静态区间第k大(分桶法和平方分割)的更多相关文章
- poj2104&&poj2761 (主席树&&划分树)主席树静态区间第k大模板
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 43315 Accepted: 14296 Ca ...
- HDU3473--Minimum Sum(静态区间第k大)
Minimum Sum Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- 静态区间第k大(归并树)
POJ 2104为例 思想: 利用归并排序的思想: 建树过程和归并排序类似,每个数列都是子树序列的合并与排序. 查询过程,如果所查询区间完全包含在当前区间中,则直接返回当前区间内小于所求数的元素个数, ...
- 主席树(静态区间第k大)
前言 如果要求一些数中的第k大值,怎么做? 可以先就这些数离散化,用线段树记录每个数字出现了多少次. ... 那么考虑用类似的方法来求静态区间第k大. 原理 假设现在要有一些数 我们可以对于每个数都建 ...
- 可持久化线段树(主席树)——静态区间第k大
主席树基本操作:静态区间第k大 #include<bits/stdc++.h> using namespace std; typedef long long LL; ,MAXN=2e5+, ...
- 数据结构2 静态区间第K大/第K小
给定数组$A[1...N]$, 区间$[L,R]$中第$K$大/小的数的指将$A[L...R]$中的数从大到小/从小到大排序后的第$K$个. "静态"指的是不带修改. 这个问题有多 ...
- 主席树初步学习笔记(可持久化数组?静态区间第k大?)
我接触 OI也快1年了,然而只写了3篇博客...(而且还是从DP跳到了主席树),不知道我这个机房吊车尾什么时候才能摸到大佬们的脚后跟orz... 前言:主席树这个东西,可以说是一种非常畸形的数据结构( ...
- 主席树学习笔记(静态区间第k大)
题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输出 ...
- POJ2104-- K-th Number(主席树静态区间第k大)
[转载]一篇还算可以的文章,关于可持久化线段树http://finaltheory.info/?p=249 无修改的区间第K大 我们先考虑简化的问题:我们要询问整个区间内的第K大.这样我们对值域建线段 ...
随机推荐
- [BZOJ1005][HNOI2008]明明的烦恼 数学+prufer序列+高精度
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int N; ...
- [Luogu1848][USACO12OPEN]书架Bookshelf DP+set+决策单调性
题目链接:https://www.luogu.org/problem/show?pid=1848 题目要求书必须按顺序放,其实就是要求是连续的一段.于是就有DP方程$$f[i]=min\{f[j]+m ...
- JSP(Java Servlet Page)
一.简介 HTML HTML擅长显示一个静态的网页,但是不能调用Java程序. Servlet Servlet擅长调用Java程序和后台进行交互,但是它不擅长显示一个完整的HTML页面. 我们希望创建 ...
- oracle 安装,启动 ,plsql 连接
1.下载oracle 服务器端,正常安装,在选择桌面类或者是服务器类的时候选择服务器类. 2.下载oracle 客户端解压版 下载地址 链接:https://pan.baidu.com/s/1mi ...
- 迅为iTOP-4412物联网开发板入门学习高手进阶项目开发超树莓派
免费视频教程: 为初学者精心录制的整套视频教程全部免费,随IT技术发展而不断增添的视频教程仍然免费!一支有经验的工程师团队会始终成为您的后盾. 项目实战---全开源: 手机远程控制开发板 门禁系统 W ...
- 安卓 Android 简单数据库(增删改查)
<Button android:id="@+id/delete_btn" android:layout_width="wrap_content" andr ...
- css3 平行四边形 、大括弧
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- element-UI el-table添加序号列时序号永远都是从1开始?
Part.1 示例 当我们想在 el-table 中添加序号列时,如下: <el-table-column label="序号" type="index" ...
- vue 常用功能和命令
1. vue-cli 构建项目 # 全局安装 vue-cli $ npm install --global vue-clif # 创建一个基于 webpack 模板的新项目 $ vue init we ...
- Android ListView setEmptyView
http://my.eoe.cn/yaming/archive/879.html 1 当我们使用ListView或GridView的时候,当列表为空的时候,我们需要一个特殊的View来提示用户操作,于 ...