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 ...
随机推荐
- 获取用户真实IP,php实现
function get_client_ip() { if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv(" ...
- 解决mac上matplotlib中文无法显示问题
系统:mac os, high sierra; python3.7(by brew installed) 在网上找了很多基本上都是让下载SimHei字体,然后放到mac的matplotlib的字体 ...
- Maven 三种archetype说明
新建Maven project项目时,需要选择archetype. 那么,什么是archetype? archetype的意思就是模板原型的意思,原型是一个Maven项目模板工具包.一个原型被定义为从 ...
- Canvas几种模式的区别
1.screen space-overlay UI显示在最前方 2.screen space-camera 箭头指的是canvas 这样可以放置东西在UI前方和UI后方 3.world space 做 ...
- oracle 11g各种下载地址
Oracle Database 11g Release 2 Standard Edition and Enterprise Edition Software Downloadsoracle 数据库 1 ...
- HDU-5695-拓扑排序+优先队列
Gym Class Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- nyoj117——树状数组升级版(树状数组+离散化)
求逆序数 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中 ...
- ansible modules开发(二)
四 使用其他语言发开module cd /etc/ansible cat library/touch.sh #!/bin/sh args_file=$1 [ ! -f "$args_file ...
- Check for Palindromes
如果给定的字符串是回文,返回true,反之,返回false. 如果一个字符串忽略标点符号.大小写和空格,正着读和反着读一模一样,那么这个字符串就是palindrome(回文). 注意你需要去掉字符串多 ...
- SpringMVC启动和执行流程
Spring框架大家用得很多,相当熟悉,但是我对里面的运作比较好奇,例如bean的加载和使用,和我们定义的配置文件有什么联系;又例如aop在什么时候起作用,原理又是怎样.经过一个了解后,整理了启动和执 ...