区间第k小

金牌导航 整体二分-1

题目大意

给出一个序列,有若干查询,每次查询给出l,r,k,让你求l~r这个区间的第k大

输入样例

7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3

输出样例

5
6
3

数据范围

1⩽n⩽105,1⩽m⩽50000,1⩽∣ai∣⩽1091\leqslant n \leqslant 10^5,1\leqslant m\leqslant 50000, 1\leqslant |a_i|\leqslant 10^91⩽n⩽105,1⩽m⩽50000,1⩽∣ai​∣⩽109

解题思路

先把原序列按数值排序
然后对于所有查询进行整体二分
对于每一段的二分,先将mid左侧的数按原下标存进树状数组,然后每个查询判断它查询的区间是否个数大于k
然后继续分治

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 100010
#define M 50010
using namespace std;
int n, m, c[N], ans[N];
struct node
{int v, s;bool operator <(const node &b) const{return s < b.s;}
}s[N];
struct nodee
{int l, r, k, v;
}a[M], b[M];
void add(int x, int y)
{for (; x <= n; x += x & -x)c[x] += y;return;
}
int ask(int x)
{int sum = 0;for (; x; x -= x & -x)sum += c[x];return sum;
}
void solve(int l, int r, int L, int R)
{if (l == r){for (int i = L; i <= R; ++i)ans[a[i].v] = s[l].s;//计算结果return;}int mid = l + r >> 1, L1 = L, R1 = R;for (int i = l; i <= mid; ++i)add(s[i].v, 1);//存数for (int i = L; i <= R; ++i){int g = ask(a[i].r) - ask(a[i].l - 1);if (a[i].k <= g) b[L1++] = a[i];//整体二分else{b[R1] = a[i];b[R1--].k -= g; }}for (int i = L; i <= R; ++i)a[i] = b[i]; for (int i = l; i <= mid; ++i)add(s[i].v, -1);if (L1 > L) solve(l, mid, L, L1 - 1);if (R1 < R) solve(mid + 1, r, R1 + 1, R);
}
int main()
{scanf("%d%d", &n, &m);for (int i = 1; i <= n; ++i){scanf("%d", &s[i].s);s[i].v = i;}sort(s + 1, s + 1 + n);for (int i = 1; i <= m; ++i){scanf("%d%d%d", &a[i].l, &a[i].r, &a[i].k);a[i].v = i;}solve(1, n, 1, m);for (int i = 1; i <= m; ++i)printf("%d\n", ans[i]);return 0;
}

【整体二分】区间第k小(金牌导航 整体二分-1)相关推荐

  1. The UVALIVE 7716 二维区间第k小

    The UVALIVE 7716 二维区间第k小 /** 题意:给一个n * n的矩阵,有q个查询每次查询r,c,s,k表示已(r,c)为右上角 大小为s的正方形中 第k小的元素n <= 250 ...

  2. 【XSY2720】区间第k小 整体二分 可持久化线段树

    题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...

  3. 动态区间第k小:树状数组套权值线段树

    所谓树状数组套权值线段树,就是在树状树组上套权值线段树 (逃) 解析 如何解决静态区间第k小? 使用主席树就ok啦 辣么如何解决动态区间第k小嘞- 我们想想主席树为啥不能解决动态区间第k小 因为如果改 ...

  4. 【代码源 Div1 - 108】#464. 数数(主席树,区间比k小的数的个数)HDU4417

    problem solution 主席树查询区间比k小的数的个数 建树之后直接在目标区间的主席树内将 H 作为挡板递归计数. #include<bits/stdc++.h> using n ...

  5. K-th Closest Distance HDU - 6621(第k小绝对值+主席树+二分)

    You have an array: a1, a2, , an and you must answer for some queries. For each query, you are given ...

  6. 【莫队】区间不同数(金牌导航 莫队-1)

    区间不同数 金牌导航 莫队-1 题目大意 给出n个数,然后询问m次,每次询问一个区间内不同的数的个数 样例输入 6 1 2 3 4 3 5 3 1 2 3 5 2 6 样例输出 2 2 4 数据范围 ...

  7. LeetCode 668. 乘法表中第k小的数(二分查找)

    文章目录 1. 题目 2. 解题 1. 题目 几乎每一个人都用 乘法表.但是你能在乘法表中快速找到第k小的数字吗? 给定高度m .宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k ...

  8. LeetCode 378. 有序矩阵中第K小的元素(二分查找)

    文章目录 1. 题目 2. 解题 2.1 暴力法 2.2 二分查找 1. 题目 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素. 请注意,它是排序后的第k小元素,而 ...

  9. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

最新文章

  1. 为什么要选择Apache Pulsar(一)
  2. Linux五部分的含义,Linux 目录下部分重要目录的用途及含义及一些命令的作用
  3. 关于SAP CRM中间件系统搭建中遇到的一些问题
  4. 信息学奥赛一本通 2057:【例3.9 】星期几
  5. Java服务,内存OOM问题如何快速定位?
  6. 关于:程序兼容多种数据库
  7. 理解 LruCache 机制
  8. 摘android手机自带浏览器无法识别apk文件
  9. 4G 全网通DTU是什么 有哪些功能应用
  10. 妖精为什么吃不到唐僧肉
  11. (转)50本书总结的50句话
  12. 最新红包抓娃娃源码带教程
  13. BIOS 工作流程解析
  14. Xshell 配置突出显示集(关键字高亮)
  15. GameFramework篇:使用源码替换GameFramework.dll
  16. 海南大学计算机学院张一教授,应用数学专业01级校友:王志刚——海南大学信息科学技术学院教授...
  17. Java游戏服务器代码热更新
  18. MeeGo handset 1.1开发环境[5]:一个desktop小应用
  19. 浙江大学python编程csdn_怎样学 Python?
  20. 【生活记事录】金字塔原理

热门文章

  1. php导出数据库的指定表数据,MYSQL教程mysql数据库导出指定表数据的方法
  2. request-promise 获取返回头信息_http返回的状态码 大全
  3. java 验证登陆_java登陆界面验证
  4. pdo mysql_PDO MySQL
  5. ai进入轮廓模式怎么退出_详解AI中扩展、扩展外观、轮廓化描边、创建轮廓
  6. dijkstra算法和floyd算法(C语言)
  7. Java 12 switch表达式新特性(->,yield)
  8. LeetCode 04检查平衡性-简单
  9. 群晖python套件包_利用群晖Docker安装ubuntu16.04搭建python网站服务器(部署篇)
  10. python中函数的参数类型( 位置参数、关键字参数、默认值参数和可变长度参数)