解题关键:由于需要根据平衡进行重建,所以不能进行去重,否则无法保证平衡性。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll; const double alpha=0.7;
const int N=1e5+;
int n; namespace ScapegoatTree{
struct node{
int l,r,v,sz,valid;
bool del;
}t[N<<];
int tot=,rt=;
#define ls(o) t[o].l
#define rs(o) t[o].r
#define pb push_back
int new_node(int x){++tot;t[tot].l=t[tot].r=;t[tot].v=x;t[tot].sz=t[tot].valid=;t[tot].del=;return tot;}
bool Bad(int o){
return (double)t[ls(o)].sz>alpha*t[o].sz||(double)t[rs(o)].sz>alpha*t[o].sz;
}
void Updata(int o){
t[o].sz=t[ls(o)].sz+t[rs(o)].sz+;
t[o].valid=t[ls(o)].valid+t[rs(o)].valid+!t[o].del;
}
void Dfs(int o,std::vector<int> &v){
if(!o) return;
Dfs(ls(o),v);
if(!t[o].del) v.pb(o);
Dfs(rs(o),v);
}
int Build(std::vector<int> &v,int l,int r){
if(l>r) return ;//原因是右边界不包含
int mid=(l+r)>>,o=v[mid];
ls(o)=Build(v,l,mid-);
rs(o)=Build(v,mid+,r);
Updata(o);
return o;
}
void ReBuild(int &o){
std::vector<int>v;
Dfs(o,v);
o=Build(v,,(int)v.size()-);
}
void Insert(int x,int &o){
if(!o){
o=new_node(x);
return ;
}
if(x>=t[o].v) Insert(x,rs(o));
else Insert(x,ls(o));
Updata(o);
if(Bad(o)) ReBuild(o);
return;
}
//del with rnk
void Delete(int o,int Rnk){
if(!t[o].del&&Rnk==t[ls(o)].valid+) {
t[o].del=;
--t[o].valid;
return;
}
if(Rnk<=t[ls(o)].valid+!t[o].del) Delete(ls(o),Rnk);
else Delete(rs(o),Rnk-t[ls(o)].valid-!t[o].del);
Updata(o);
}
int GetRank(int o,int x){
int ans=;
while(o){
if(t[o].v>=x) o=ls(o);
else{
ans+=t[ls(o)].valid+!t[o].del;
o=rs(o);
}
}
return ans;
}
int FindKth(int o,int x) {
while(o){
if(!t[o].del&&t[ls(o)].valid+==x) {return t[o].v;}
if(t[ls(o)].valid>=x) o=ls(o);
else {
x-=t[ls(o)].valid+!t[o].del;
o=rs(o);
}
}
}
int GetPred(int o,int x){
return FindKth(o,GetRank(o,x)-);
}
int GetSucc(int o,int x){
return FindKth(o,GetRank(o,x+));
}
}
using namespace ScapegoatTree; int main() {
scanf("%d",&n);
rt=;
while(n--) {
int op,x;
scanf("%d%d",&op,&x);
if(op==) Insert(x,rt);
if(op==) Delete(rt,GetRank(rt,x));
if(op==) printf("%d\n",GetRank(rt,x));
if(op==) printf("%d\n",FindKth(rt,x));
if(op==) printf("%d\n",GetPred(rt,x));
if(op==) printf("%d\n",GetSucc(rt,x));
}
return ;
}

最新文章

  1. eclipse中的任务标记(TODO、FIXME、XXX)
  2. LeetCode Palindrome Permutation II
  3. uva 839 Not so Mobile-S.B.S.
  4. python脚本实例001 - 通过列表内容判断输入输出信息
  5. HDU 2952 Counting Sheep(DFS)
  6. C++字节对齐汇总
  7. Java知多少(79)哈希表及其应用
  8. Java JDBC的基础知识(四)
  9. IIS7.5标识介绍
  10. JavaScript 数组(Array)对象
  11. Charles做代理的Map Remote路径配置
  12. R语言使用RMySQL连接及读写Mysql数据库 测试通过
  13. 0_Simple__simplePitchLinearTexture
  14. XmlHttpRequest对象 ajax核心之一
  15. Win32:引用头文件
  16. 中文乱码—Servlet—SpringMVC
  17. mysql总结(三)
  18. mac 写NTFS磁盘
  19. 【Android】ListView、RecyclerView异步加载图片引起错位问题
  20. weblogic应用加载不上

热门文章

  1. 【剑指offer】数组中的逆序对,C++实现
  2. 通过ssh限制ip访问
  3. Spring3.x JSR-303
  4. 剑指offer-第四章解决面试题的思路(从上往下打印二叉树)
  5. 转载.怎样在Quartus II中转化HDL文件为bsf文件?
  6. Spring源码学习之:ClassLoader学习(5)-自测
  7. 【java规则引擎】规则引擎RuleBase中利用观察者模式
  8. EXCEL类型库的添加
  9. liunx基础(5)
  10. yii2 csrf验证原理分析