题目描述

这是一道模板题,其数据比「普通平衡树」更强。

如未特别说明,以下所有数据均为整数。

维护一个多重集 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. 维护全序集【树状数组维护全序集】的更多相关文章

  1. [poj3378] Crazy Thairs (DP + 树状数组维护 + 高精度)

    树状数组维护DP + 高精度 Description These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ...

  2. HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gc ...

  3. POJ 3321 Apple Tree(后根遍历将树转化成序列,用树状数组维护)

    题意:一棵树,有很多分叉,每个分叉上最多有1个苹果. 给出n,接下来n-1行,每行u,v,表示分叉u,v之间有树枝相连.这里数据中u相当于树中的父节点,v相当于子节点. 给出两个操作: 1.C x  ...

  4. 【Hihocoder 1167】 高等理论计算机科学 (树链的交,线段树或树状数组维护区间和)

    [题意] 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 少女幽香这几天正在学习高等理论计算机科学,然而她什么也没有学会,非常痛苦.所以她出去晃了一晃,做起了一些没什么意 ...

  5. 第十二届湖南省赛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 ...

  6. 【BZOJ2124】等差子序列 树状数组维护hash值

    [BZOJ2124]等差子序列 Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N ...

  7. ACM-ICPC 2018 徐州赛区网络预赛 G. Trace【树状数组维护区间最大值】

    任意门:https://nanti.jisuanke.com/t/31459 There's a beach in the first quadrant. And from time to time, ...

  8. 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 ...

  9. 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...

随机推荐

  1. Dubbo通过注解实现RPC调用

    启动Dubbo服务有2个方式,1是通过xml配置,2是通过注解来实现,这点和Spring相似. 采用XML配置如下:  <?xml version="1.0" encodin ...

  2. python脚本10_打印斐波那契数列的第101项

    #打印斐波那契数列的第101项 a = 1 b = 1 for count in range(99): a,b = b,a+b else: print(b) 方法2: #打印斐波那契数列的第101项 ...

  3. 2-3 sshd服务---暴力破解应对策略

      sshd服务暴力破解步骤 sshd暴力破解方法 防止暴力破解调优 1. 变更默认端口 2. 变更root用户 3. 日志监控-->防止暴力破解(fail2ban应用) fail2ban详解 ...

  4. C# - Generics泛型,一图话c#泛型

    一.一篇好文 https://www.cnblogs.com/yueyue184/p/5032156.html 二.一幅好图

  5. 打开Eclipse提示“The default workspace “xxxx” is in use or cannot be created Please choose a different one“

    原因:出现这种情况一般是workspace的配置文件中出现了.lock文件(workspace/.metadata/.lock),锁定了workspace.把.lock文件删除即可. 如果该文件不能删 ...

  6. python2 commands模块在python3.x被subprocess取代

    subprocess 可以执行shell命令的相关模块和函数有: os.systemos.spawnos.popen --废弃popen2.* --废弃commands.* --废弃,3.x中被移除 ...

  7. Highcharts 动态图

    Highcharts 动态图 每秒更新曲线图 chart.events chart.event 属性中添加 load 方法(图表加载事件).在 1000 毫秒内随机产生数据点并生成图表. chart: ...

  8. 安装magento主题模板

    magento 的强大功能自不必说, 另外还有一点更重要的是拥有很多顶级的精致模板开发者和爱好者的支持开发出种类繁多, 用途各异的模板, 深受用户的喜爱, 但是安装模板对于初次使用者或者很久没有使用者 ...

  9. C#笔记 -- 协变、逆变

    协变 理解:在泛型和委托中, 让使用某个泛型参数A的类型可以用一个使用由A派生的泛型参数B的类型实例化,(小=> 大)如 ​ // IEnumerable<Animal> 与 Lis ...

  10. bzoj3400

    题解: dp f[i][j]表示前i个,膜为j 最后记得判断0 代码: #include<bits/stdc++.h> using namespace std; ; int n,m,a[N ...