K-th Number 线段树的区间第K大
http://poj.org/problem?id=2104
由于这题的时间限制不紧,所以用线段树水一水。
每个节点保存的是一个数组。
就是对应区间排好序的数组。
建树的时间复杂度需要nlogn
然后查询的时候,对于线段树覆盖了的区间,可以直接二分即可。
查询复杂度需要logn^2
所以复杂度需要mlognlogn
对于怎么确定是那个元素。可以二分一个值val
然后查询在个val在这个区间是否第k大即可。
所以复杂度需要mlognlognlog1e9
开始的时候,不知道怎么确定2、3、5、6的第3大。
我以为二分一个4出来也是第三大啊。
但4只是第二大,如果把它放进去数组里面,当然变成了第3大,但是现在是统计小于等于4的个数,只有2个。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#define root 1, n, 1
#define lson L, mid, cur << 1
#define rson mid + 1, R, cur << 1 | 1
const int maxn = + ;
vector<int>seg[maxn << ];
int a[maxn];
int n, m;
void pushUp(int cur) {
merge(seg[cur << ].begin(), seg[cur << ].end(), seg[cur << | ].begin(), seg[cur << | ].end(), seg[cur].begin());
}
void build(int L, int R, int cur) {
if (L == R) {
seg[cur].clear();
seg[cur].push_back(a[L]);
return;
}
int mid = (L + R) >> ;
build(lson);
build(rson);
seg[cur].resize(R - L + );
pushUp(cur);
}
int query(int be, int en, int val, int L, int R, int cur) {
if (L >= be && R <= en) {
if (val >= seg[cur].back()) {
return R - L + ;
} else {
int pos = upper_bound(seg[cur].begin(), seg[cur].end(), val) - seg[cur].begin();
return pos;
}
}
int mid = (L + R) >> ;
int lans = , rans = ;
if (mid >= be) {
lans = query(be, en, val, lson);
}
if (mid < en) {
rans = query(be, en, val, rson);
}
return lans + rans;
}
int tofind(int L, int R, int k) {
int be = -1e9;
int en = 1e9;
while (be <= en) {
int mid = (be + en) >> ;
if (query(L, R, mid, root) >= k) {
en = mid - ;
} else be = mid + ;
}
return be;
}
void work() {
scanf("%d%d", &n, &m);
// cout << n << " " << m << endl;
for (int i = ; i <= n; ++i) {
scanf("%d", &a[i]);
}
build(root);
while (m--) {
int L, R, k;
scanf("%d%d%d", &L, &R, &k);
printf("%d\n", tofind(L, R, k));
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}
分块超时代码,不解
一直TLE, 20多次
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = + ;
int arr[maxn];
int tarr[maxn];
int tosort[maxn];
int n, m;
int magic;
void init() {
for (int i = ; i <= n;) {
if (i + magic - > n) break;
sort(tosort + i, tosort + i + magic);
i += magic;
}
}
bool check(int L, int R, int val, int k) {
int ans = ;
for (int i = L; i <= R;) {
if (i % magic == && i + magic - <= R) {
ans += upper_bound(tosort + i, tosort + i + magic, val) - (tosort + i - ) - ;
i += magic;
} else {
if (val >= arr[i]) {
ans++;
}
++i;
}
if (ans >= k) return true;
}
return false;
}
int calc(int L, int R, int k) {
int be = , en = n;
while (be <= en) {
int mid = (be + en) >> ;
if (check(L, R, tarr[mid], k)) {
en = mid - ;
} else be = mid + ;
}
return tarr[be];
}
void work() {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i) {
scanf("%d", &arr[i]);
tarr[i] = arr[i];
tosort[i] = arr[i];
}
sort(tarr + , tarr + + n);
magic = (n / ((int)sqrt(n * log((double)n)) + ));
init();
// cout << check(1, 7, 3, 3) << endl;
while (m--) {
int L, R, k;
scanf("%d%d%d", &L, &R, &k);
printf("%d\n", calc(L, R, k));
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}
K-th Number 线段树的区间第K大的更多相关文章
- 线段树维护区间前k小
线段树维护区间前k小 $ solution: $ 觉得超级钢琴太麻烦?在这里线段树提供一条龙服务 . 咳咳,开始讲正题!这道题我们有一个和超级钢琴复杂度一样 $ ~O(~\sum x\times lo ...
- [hdu2665]Kth number(划分树求区间第k大)
解题关键:划分树模板题. #include<cstdio> #include<cstring> #include<algorithm> #include<cs ...
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)
题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...
- 【bzoj3110】[Zjoi2013]K大数查询 权值线段树套区间线段树
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- A - 低阶入门膜法 - K-th Number (主席树查询区间第k小)
题目链接:https://cn.vjudge.net/contest/284294#problem/A 题目大意:主席树查询区间第k小. 具体思路:主席树入门. AC代码: #include<i ...
- hdu 1698:Just a Hook(线段树,区间更新)
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu1698线段树的区间更新区间查询
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU-6315 Naive Operations//2018 Multi-University Training Contest 2___1007 (线段树,区间除法)
原题地址 Naive Operations Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 502768/502768 K (Java/ ...
随机推荐
- gdb调试使用autotools工程的项目
1 保留debug sympol和优化等级设置为-O0的最简单的方法 在执行configure脚本生成Makefile文件时,使用CXXFLAGS宏,因为标准的configure脚本给了这个宏. .. ...
- HDFS vs. MongoDB
HDFS MongoDB 共同点 http://www.mongoing.com/wp-content/uploads/2016/08/MDBSH2016/TJ_MongoDB+Spark.pdf 横 ...
- HTML5 and Websocket
在HTML5规范中,我最喜欢的Web技术就是正迅速变得流行的WebSocket API.WebSocket提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术.这个新的API提供了一个方法 ...
- 【POJ3740】Easy Finding DLX(Dancing Links)精确覆盖问题
题意:多组数据,每组数据给你几行数,要求选出当中几行.使得每一列都有且仅有一个1.询问是可不可行,或者说能不能找出来. 题解:1.暴搜.2.DLX(Dancing links). 本文写的是DLX. ...
- Kafka在Windows安装运行
摘要:本文主要说明了如何在Windows安装运行Kafka 一.安装JDK 过程比较简单,这里不做说明. 最后打开cmd输入如下内容,表示安装成功 二.安装zooeleeper 下载安装包:http: ...
- Spring Boot2.0之 整合Redis集群
项目目录结构: pom: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:// ...
- YTU 2802: 判断字符串是否为回文
2802: 判断字符串是否为回文 时间限制: 1 Sec 内存限制: 128 MB 提交: 348 解决: 246 题目描述 编写程序,判断输入的一个字符串是否为回文.若是则输出"Yes ...
- YTU 2424: C语言习题 字符串比较
2424: C语言习题 字符串比较 时间限制: 1 Sec 内存限制: 128 MB 提交: 1042 解决: 613 题目描述 写一函数,实现两个字符串的比较.即自己写一个strcmp函数,函数 ...
- 使用PHP对word文档进行操作的方法
使用php时,因为加密等原因,如果直接用FILE后者OPEN等函数读取WORD的话往往是乱码,原来要使用COM 这是我简单的一个读取并存储到新的WORD上的文件<? // 建立一个指向新COM组 ...
- 奶牛排序——RMQ
[问题描述]奶牛在熊大妈的带领下排成了一条直队.显然,不同的奶牛身高不一定相同……现在,奶牛们想知道,如果找出一些连续的奶牛,要求最左边的奶牛 A 是最矮的,最右边的 B 是最高的,且 B 高于 A ...