【bzoj3224】【Tyvj 1728】 普通平衡树 树状数组
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入$x$数
2. 删除$x$数(若有多个相同的数,因只删除一个)
3. 查询$x$数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为$x$的数
5. 求$x$的前驱(前驱定义为小于$x$,且最大的数)
6. 求$x$的后继(后继定义为大于$x$,且最小的数)
数据范围:操作数$≤10^5$,$x≤10^9$。
这一题用平衡树做的方法是显然的,然而平衡树太长太慢,我们考虑写一个优美一点的算法。
首先先离散化所有读入的数(别离散化操作4!!!!)
然后,插入和删除操作显然(直接在离散化后的x处,赋值+1或者-1即可)
查询某个数的排名也是显然的。
考虑查询排名为$x$如何高速完成,此处不妨设$x$为正整数。
我们求一个最小的$p$,使得$2^p≥cnt$,其中$cnt$为树状数组的长度。
设当前访问到的点为$id$(初始为$0$)
我们每次查询$a[id+2^p]$上的值是否小于$x$,如果是$x$,那么$id+=2^p$,然后$x-=a[id]$。
然后p--即可。
最后输出$id+1$即是第$k$大的数。
求前驱和后继:先求出给出的数是第几大的,然后$+1$或$-1$即可。
代码奇短
#include<bits/stdc++.h>
#define M 200000
#define lowbit(x) ((x)&(-x))
using namespace std;
int a[M]={},c[M]={},n,cnt=,m;
int op[M]={},b[M]={};
void add(int x,int k){for(;x<=n;x+=lowbit(x)) a[x]+=k;}
int sum(int x){int k=;for(;x;x-=lowbit(x)) k+=a[x]; return k;}
int getkth(int k){
int id=;
for(int i=n;i;i>>=){
if(k>a[id+i])
k-=a[id+i],id+=i;
}
return id+;
}
int main(){
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%d%d",op+i,b+i);
if(op[i]!=) c[++cnt]=b[i];
}
sort(c+,c+cnt+);
for(int i=;i<=m;i++)
if(op[i]!=) b[i]=lower_bound(c+,c+cnt+,b[i])-c;
for(n=;n<=cnt;n<<=);
for(int i=;i<=m;i++){
if(op[i]==) add(b[i],);
if(op[i]==) add(b[i],-);
if(op[i]==) printf("%d\n",sum(b[i]-)+);
if(op[i]==) printf("%d\n",c[getkth(b[i])]);
if(op[i]==) printf("%d\n",c[getkth(sum(b[i]-))]);
if(op[i]==) printf("%d\n",c[getkth(sum(b[i])+)]);
}
}
【bzoj3224】【Tyvj 1728】 普通平衡树 树状数组的更多相关文章
- [BZOJ3224]Tyvj 1728 普通平衡树
[BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...
- bzoj3224: Tyvj 1728 普通平衡树(平衡树)
bzoj3224: Tyvj 1728 普通平衡树(平衡树) 总结 a. cout<<(x=3)<<endl;这句话输出的值是3,那么对应的,在splay操作中,当父亲不为0的 ...
- bzoj3224 Tyvj 1728 普通平衡树(名次树+处理相同)
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5354 Solved: 2196[Submit][Sta ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- bzoj3196 二逼平衡树 树状数组套线段树
题目传送门 思路:树状数组套线段树模板题. 什么是树状数组套线段树,普通的树状数组每个点都是一个权值,而这里的树状数组每个点都是一颗权值线段树,我们用前缀差分的方法求得每个区间的各种信息, 其实关键就 ...
- luogu3380/bzoj3196 二逼平衡树 (树状数组套权值线段树)
带修改区间K大值 这题有很多做法,我的做法是树状数组套权值线段树,修改查询的时候都是按着树状数组的规则找出那log(n)个线段树根,然后一起往下做 时空都是$O(nlog^2n)$的(如果离散化了的话 ...
- bzoj3224: Tyvj 1728 普通平衡树(splay)
3224: Tyvj 1728 普通平衡树 题目:传送门 题解: 啦啦啦啦又来敲个模版水经验啦~ 代码: #include<cstdio> #include<cstring> ...
- 【权值线段树】bzoj3224 Tyvj 1728 普通平衡树
一个板子. #include<cstdio> #include<algorithm> using namespace std; #define N 100001 struct ...
- 替罪羊树—BZOJ3224: Tyvj 1728 普通平衡树
冬令营被平衡树坑了之后,打算苦练一番数据结构(QAQ). 先是打了一下想学好久的替罪羊树. 替罪羊树实现方法很简单,就是在不满足平衡条件的时候暴力重构子树. 调试小结: 1.删除操作分两类情况:如果某 ...
随机推荐
- C语言基础第三次作业
题目7-1,寻找最小值 1.实验代码: #include<stdio.h> int main() { int i,mark,min,n; scanf("%d", &am ...
- MyEclipse配置Maven插件
一.工具环境 1.jdk-7u80-windows-x64 2.apache-tomcat-7.0.70 3.apache-maven-3.3.9 4.MyEclipse 10.7 5.windows ...
- 2018.10.08 NOIP模拟 斐波那契(贪心+hash/map)
传送门 签到题. 显然是可以贪心分组的,也就是尽量跟当前的分成一组. 这时我们需要判断a[l]+a[r],a[l+1]+a[r]...a[r−1]+a[r]a[l]+a[r],a[l+1]+a[r]. ...
- origin里用c语言编程
学习自白东升老师的origin8.0课程. 其实是originC语言.origin中大多绘图和处理功能都是originC语言完成的,可以同时按下ctrl和shift然后点击相应的功能,就会出现每个按钮 ...
- StackView实现叠加在一起的图片循环移动像循环队列一样
MainActivity.java public class MainActivity extends Activity { StackView stackView; int[] imageIds ...
- 编写属于自己的linux命令
开篇: 问题和解决思路 在使用一些基础IDE时,工具经常会在我们建立特定文件时给我们一个已经有了一些特定代码的模板文件,但是在linux开发时,没有这样的IDE,怎么办?虽然代码量不是很多,但是能一次 ...
- 2、WindowManager源码分析--最后一战
在最后一站中,几乎所有的UI界面都是这个WindowManager管理的,那么他是如何调度的呢?我们来看看一些项目中的界面. 上面有登陆界面,专门管理登陆.战斗界面,用户界面,专门管理用户属性等等. ...
- faceswap使用手冊
cd faceswap cd faceswap-master python faceswap.py gui Notice: This repository is not operated or mai ...
- 常用算法 (JS实现)
全排序列 function swap(array,a,b){ var m=array[a]; array[a]=array[b]; array[b]=m; } function full_sort(a ...
- hdu 4998 矩阵表示旋转
http://acm.hdu.edu.cn/showproblem.php?pid=4998 http://blog.csdn.net/wcyoot/article/details/33310329 ...