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/ ...
随机推荐
- chmod|chown|chgrp和用法和区别
1.chgrp(改变文件所属用户组) chgrp 用户组 文件名 ###就是这个格了.如果整个目录下的都改,则加-R参数用于递归. 如:chgrp -R user smb.conf 2.c ...
- 使用 fetch 代替 ajax(在不支持的浏览器上使用 XHR); This kind of functionality was previously achieved using XMLHttpRequest.
原生 JS Ajax,GET和POST 请求实例代码_javascript技巧_脚本之家 https://www.jb51.net/article/86157.htm 更新时间:2016年06月08日 ...
- MyEclipse 8.5 启动过程优化
前言:MyEclipse5.5 大小 139M:MyEclipse6.5 大小 451M:MyEclipse7.0 大小 649M:MyEclipse8.0 大小 772.3MB(速度方面比7.1和7 ...
- Kafka使用经验小结
本文尽量从一个使用者的角度去记录一些在实战当中使用Kfaka所需要关注的要点,这样可能会贴切更多的读者,本文并不会介绍太多的Kafka的一些架构层次设计的知识,因为网上已经有一大堆的重复搬运的资料任由 ...
- Unable to instantiate receiver XXXXXX
运行一个工程的时候时logcat中出现了“Unable to instantiate receiver XX..”. 检查后发现,由于是东拼西凑的代码,所以在Manifest文件里注册了Receive ...
- Eclipse中文乱码问题
最近用TortoiseSVN从androiddex上下载了一个android工程,导入之后发现里面的中文都是乱码,于是在Eclipse里通过Windows-Preferences-Workspace修 ...
- you are the one(区间dp)
传送门 You Are the One Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- unittest参数化parameterized
参考文章: https://www.cnblogs.com/royfans/p/7226360.html https://blog.csdn.net/zha6476003/article/detail ...
- git只clone仓库中指定子目录
基于sparse clone变通方法 [root@vm_test backup]# mkdir devops[root@vm_test backup]# cd devops/[root@vm_test ...
- Linux限制端口
设置防火墙 iptables -a input -p 协议 -s 可以访问ip -dport端口 -j ACCEPT