LOJ107. 维护全序集【树状数组维护全序集】
题目描述
这是一道模板题,其数据比「普通平衡树」更强。
如未特别说明,以下所有数据均为整数。
维护一个多重集 S ,初始为空,有以下几种操作:
把 x 加入 S
删除 S 中的一个 x,保证删除的 x 一定存在
求 S 中第 k 小
求 S 中有多少个元素小于 x
求 S 中小于 x 的最大数
求 S 中大于 x 的最小数
操作共 n 次。
输入格式
第一行一个整数 n,表示共有 n 次操作 。
接下来 n 行,每行为以下几种格式之一 :
0 x,把 x 加入 S
1 x,删除 S 中的一个 x,保证删除的数在 S 中一定存在
2 k,求 S 中第 k 小的数,保证要求的数在 S 中一定存在
3 x,求 S 中有多少个数小于 x
4 x,求 S 中小于 x 的最大数,如果不存在,输出 −1
5 x,求 S 中大于 x 的最小数,如果不存在,输出 −1
输出格式
对于每次询问,输出单独一行表示答案。
样例
样例输入
5
0 3
0 4
2 2
1 4
3 3
样例输出
4
0
数据范围与提示
$ 1 \leq n \leq 3 \times 10 ^ 5, 0 \leq x \leq 10 ^ 9$
思路
平衡数已经烂大街了
我就来讲讲bit怎么维护全序集吧
除了bit的常规操作,核心技能只有一个
就是找序列的第k大
这个东西是可以在树状数组上二分的
你会发现对于任何一个bit上的节点
它左子树上的任何一个节点都是对应右子树上的一个节点加上一个二进制位得到的
并且这个二进制位恰好是这个节点儿子的层数所对应的二进制位
所以就可以直接看这个二进制位到底要不要选
在bit上二分并迭代就可以了
好神仙的操作啊
//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
//typename
typedef long long ll;
//convenient for
#define fu(a, b, c) for (int a = b; a <= c; ++a)
#define fd(a, b, c) for (int a = b; a >= c; --a)
#define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
//inf of different typename
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
//fast read and write
template <typename T>
void Read(T &x) {
bool w = 1;x = 0;
char c = getchar();
while (!isdigit(c) && c != '-') c = getchar();
if (c == '-') w = 0, c = getchar();
while (isdigit(c)) {
x = (x<<1) + (x<<3) + c -'0';
c = getchar();
}
if (!w) x = -x;
}
template <typename T>
void Write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) Write(x / 10);
putchar(x % 10 + '0');
}
//----------------------------------------------
//树状数组维护全序集
const int N = 1e6 + 10;
int tot = 0, n, up = 1;
int a[N], b[N], op[N];
int bit[N], lowbit[N];
inline void insert(int vl) {
for (; vl <= tot; vl += lowbit[vl]) ++bit[vl];
}
inline void del(int vl) {
for (; vl <= tot; vl += lowbit[vl]) --bit[vl];
}
inline int query(int vl) {
int res = 0;
for (; vl; vl -= lowbit[vl]) res += bit[vl];
return res;
}
inline int kth(int vl) {
int res = 0;
for (int i = up; i; i >>= 1) {
if (bit[res | i] < vl && (res | i) <= tot) {
res |= i;
vl -= bit[res];
}
}
return res + 1;
}
inline int getpre(int vl) {return kth(query(vl - 1));}
inline int getnxt(int vl) {return kth(query(vl) + 1);}
int main() {
Read(n);
fu(i, 1, n) {
Read(op[i]);
Read(a[i]);
if (op[i] != 2) b[++tot] = a[i];
}
b[++tot] = -1;
sort(b + 1, b + tot + 1);
tot = unique(b + 1, b + tot + 1) - b - 1;
b[tot + 1] = -1;
fu(i, 1, tot) lowbit[i] = i & (-i);
while (up <= tot) up <<= 1; up >>= 1;
fu(i, 1, n) {
if (op[i] != 2) a[i] = lower_bound(b + 1, b + tot + 1, a[i]) - b;
switch (op[i]) {
case 0:insert(a[i]);break;
case 1:del(a[i]);break;
case 2:Write(b[kth(a[i])]);putchar('\n');break;
case 3:Write(query(a[i] - 1));putchar('\n');break;
case 4:Write(b[getpre(a[i])]);putchar('\n');break;
case 5:Write(b[getnxt(a[i])]);putchar('\n');break;
}
}
return 0;
}
LOJ107. 维护全序集【树状数组维护全序集】的更多相关文章
- [poj3378] Crazy Thairs (DP + 树状数组维护 + 高精度)
树状数组维护DP + 高精度 Description These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ...
- HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gc ...
- POJ 3321 Apple Tree(后根遍历将树转化成序列,用树状数组维护)
题意:一棵树,有很多分叉,每个分叉上最多有1个苹果. 给出n,接下来n-1行,每行u,v,表示分叉u,v之间有树枝相连.这里数据中u相当于树中的父节点,v相当于子节点. 给出两个操作: 1.C x ...
- 【Hihocoder 1167】 高等理论计算机科学 (树链的交,线段树或树状数组维护区间和)
[题意] 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 少女幽香这几天正在学习高等理论计算机科学,然而她什么也没有学会,非常痛苦.所以她出去晃了一晃,做起了一些没什么意 ...
- 第十二届湖南省赛G - Parenthesis (树状数组维护)
Bobo has a balanced parenthesis sequence P=p 1 p 2…p n of length n and q questions. The i-th questio ...
- 【BZOJ2124】等差子序列 树状数组维护hash值
[BZOJ2124]等差子序列 Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N ...
- ACM-ICPC 2018 徐州赛区网络预赛 G. Trace【树状数组维护区间最大值】
任意门:https://nanti.jisuanke.com/t/31459 There's a beach in the first quadrant. And from time to time, ...
- Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains 【树状数组维护区间最大值】
题目传送门:http://codeforces.com/contest/799/problem/C C. Fountains time limit per test 2 seconds memory ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...
随机推荐
- SQL优化- in和not in
in不会导致索引失效,但最终数据库会将in语句解析为or语句,eg: select * from T_MAIN_PROCESS t where t.audit_status_code in ('05' ...
- mysql中索引利用情况(explain用法)
使用explain查看,如下 1.首先创建表test,语句如下 create table test(a int,b varchar(10),c varchar(10)); 2.在表中的a,b都创建索引 ...
- spring mvc:内部资源视图解析器(注解实现)@Controller/@RequestMapping
spring mvc:内部资源视图解析器(注解实现)@Controller/@RequestMapping 项目访问地址: http://localhost:8080/guga2/hello/prin ...
- mina-deploy(3800🌟) 快速部署工具
Mina (3800
- MongoDB.Driver 2.4以上版本 在.NET中的基本操作
MongoDB.Driver是操作mongo数据库的驱动,最近2.0以下版本已经从GitHub和Nuget中移除了,也就是说.NET Framework4.0不再能从官方获取到MongoDB的驱动了, ...
- AOP(面向切面)的粗俗理解
百度百科的解释:AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. 一个比较绕的概念,简单来说就是把不影响业 ...
- UVA-11324 The Largest Clique (强连通+DP)
题目大意:在一张无向图中,最大的节点集使得集合内任意两个节点都能到达对方. 题目分析:找出所有的强连通分量,将每一个分量视作大节点,则原图变成了一张DAG.将每个分量中的节点个数作为节点权值,题目便转 ...
- python2 commands模块在python3.x被subprocess取代
subprocess 可以执行shell命令的相关模块和函数有: os.systemos.spawnos.popen --废弃popen2.* --废弃commands.* --废弃,3.x中被移除 ...
- Ubuntu下压缩解压文件
一般来说ubuntu 下带有tar 命令,可以用来解压和压缩之用.但是我们经常要与win下用户打交道,所以要安装一些解压工具如:rar zip 等命令. 如果要需要用到zip工具那么可以: sudo ...
- Quartz教程五:SimpleTrigger
原文链接 | 译文链接 | 翻译:nkcoder 本系列教程由quartz-2.2.x官方文档翻译.整理而来,希望给同样对quartz感兴趣的朋友一些参考和帮助,有任何不当或错误之处,欢迎指正:有兴趣 ...