Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 12015  Solved: 5136

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]

Source

替罪羊树

曾经我一直以为替罪羊树就是不平衡的时候拍扁了重建……

真是拿衣服

从yhx那里get了神奇的删点方法:找到它的前驱pre,用pre代替它←虽然只有一句话,但这是整道题最麻烦的地方

http://blog.csdn.net/sdfzyhx/article/details/70212142

代码里同时用到了st,top,st2,top2两组变量,写的时候我还在想这样会不会写混,事实证明果然写混调了半天……

 /*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct node{
int l,r;
int val,sz;
int cnt;
bool operator < (const node b)const{
return val<b.val;
}
}t[mxn],vt[mxn];
int rot=;
int sz=,cnt=;
int st[mxn],top=;
int flag=,faf;
int newnode(){
int res=;
if(top)res=st[top--];
else res=++cnt;
t[res].sz=t[res].l=t[res].r=t[res].cnt=;
return res;
}
void pushup(int x){
t[x].sz=t[t[x].l].sz+t[t[x].r].sz+t[x].cnt;return;
}
void Build(int l,int r,int &rt){
if(l>r){rt=;return;}
int mid=(l+r)>>;
rt=newnode();
t[rt].val=vt[mid].val;
t[rt].cnt=vt[mid].cnt;
t[rt].sz=t[rt].cnt;
Build(l,mid-,t[rt].l);
Build(mid+,r,t[rt].r);
pushup(rt);
return;
}
void insert(int &rt,int x){
if(!rt){
rt=newnode();
t[rt].val=x;
t[rt].cnt=t[rt].sz=;
return;
}
t[rt].sz++;
if(t[rt].val==x){
t[rt].cnt++;
return;
}
if(x<t[rt].val)insert(t[rt].l,x);
else insert(t[rt].r,x);
if(t[t[rt].l].sz/(double)t[rt].sz>0.666)flag=rt;
if(flag==t[rt].l || flag==t[rt].r)faf=rt;
pushup(rt);
return;
}
void del(int rt){
if(!rt)return;
vt[++sz]=t[rt];
st[++top]=rt;
del(t[rt].l);
del(t[rt].r);
return;
}
int pre(int rt,int x){
int res=-2e9-,pos=;
while(rt){
if(t[rt].val>=x){
rt=t[rt].l;
}
else{
if(t[rt].val>res){res=t[rt].val;pos=rt;}
rt=t[rt].r;
}
}
return pos;
}
int sub(int rt,int x){
int res=2e9+,pos=;
while(rt){
if(t[rt].val<=x){
rt=t[rt].r;
}
else{
if(t[rt].val<res){res=t[rt].val;pos=rt;}
rt=t[rt].l;
}
}
return pos;
}
int st2[mxn],top2=,fafa;
void Q_erase(int &rt,int x){
// if(!rt && x==299181)while(1);
if(t[rt].val==x){
t[rt].cnt--;
t[rt].sz--;
if(!t[rt].cnt){
if(t[rt].l*t[rt].r==){rt=t[rt].l+t[rt].r;return;}
int p=t[rt].l;
while(t[p].r){st2[++top2]=p;p=t[p].r;}
if(top2){
t[st2[top2]].r=t[p].l;
pushup(st2[top2]);
t[p].l=t[rt].l;
t[p].r=t[rt].r;
while(top2)pushup(st2[top2--]);
}
else t[p].r=t[rt].r;
if(fafa){
if(t[fafa].l==rt) t[fafa].l=p;
else t[fafa].r=p;
}
pushup(p);
pushup(t[rt].l);
rt=p;
}
pushup(fafa);
return;
}
fafa=rt;
if(x<t[rt].val)Q_erase(t[rt].l,x);
else Q_erase(t[rt].r,x);
pushup(rt);
return;
}
int Q_rank(int rt,int x){
int res=;
while(rt){
if(t[rt].val<x){
res+=t[t[rt].l].sz+t[rt].cnt;
rt=t[rt].r;
}
else rt=t[rt].l;
}
return res+;
}
int Q_num(int rt,int k){
int res=;
while(rt){
if(t[t[rt].l].sz>=k){
res=t[rt].val;
rt=t[rt].l;
}
else if(t[t[rt].l].sz+t[rt].cnt>=k)return t[rt].val;
else k-=t[t[rt].l].sz+t[rt].cnt,rt=t[rt].r;
}
return res;
}
void Debug(int x){
if(!x)return;
printf("#%d: v:%d l:%d r:%d sz:%d cnt:%d\n",
x,t[x].val,t[x].l,t[x].r,t[x].sz,t[x].cnt);
Debug(t[x].l);Debug(t[x].r);
}
int n;
int main(){
// freopen("in.txt","r",stdin);
// freopen("out.out","w",stdout);
int i,j;
n=read();
int op,x;
int tct=;
while(n--){
op=read();x=read();
if(op!=)tct++;
switch(op){
case :{
flag=faf=;sz=;
insert(rot,x);
if(flag){
del(flag);
sort(vt+,vt+sz+);
if(flag==rot)Build(,sz,rot);
else Build(,sz,(t[faf].l==flag)?t[faf].l:t[faf].r);
}
break;
}
case :{fafa=;Q_erase(rot,x);break;}
case :{
int ans=Q_rank(rot,x);
printf("%d\n",ans);
break;
}
case :{
int ans=Q_num(rot,x);
printf("%d\n",ans);
break;
}
case :{
int res=pre(rot,x);
printf("%d\n",t[res].val);
break;
}
case :{
int res=sub(rot,x);
printf("%d\n",t[res].val);
break;
}
case :{
Debug(rot);
break;
}
}
}
return ;
}

Bzoj3224 / Tyvj 1728 普通替罪羊树的更多相关文章

  1. [BZOJ3224]Tyvj 1728 普通平衡树

    [BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...

  2. bzoj3224: Tyvj 1728 普通平衡树(平衡树)

    bzoj3224: Tyvj 1728 普通平衡树(平衡树) 总结 a. cout<<(x=3)<<endl;这句话输出的值是3,那么对应的,在splay操作中,当父亲不为0的 ...

  3. 替罪羊树—BZOJ3224: Tyvj 1728 普通平衡树

    冬令营被平衡树坑了之后,打算苦练一番数据结构(QAQ). 先是打了一下想学好久的替罪羊树. 替罪羊树实现方法很简单,就是在不满足平衡条件的时候暴力重构子树. 调试小结: 1.删除操作分两类情况:如果某 ...

  4. bzoj3224 Tyvj 1728 普通平衡树(名次树+处理相同)

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5354  Solved: 2196[Submit][Sta ...

  5. bzoj3224: Tyvj 1728 普通平衡树(splay)

    3224: Tyvj 1728 普通平衡树 题目:传送门 题解: 啦啦啦啦又来敲个模版水经验啦~ 代码: #include<cstdio> #include<cstring> ...

  6. 【权值线段树】bzoj3224 Tyvj 1728 普通平衡树

    一个板子. #include<cstdio> #include<algorithm> using namespace std; #define N 100001 struct ...

  7. BZOJ3224 Tyvj 1728 普通平衡树(Treap)

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  8. 【权值分块】bzoj3224 Tyvj 1728 普通平衡树

    权值分块和权值线段树的思想一致,离散化之后可以代替平衡树的部分功能. 部分操作的时间复杂度: 插入 删除 全局排名 全局K大 前驱 后继 全局最值 按值域删除元素 O(1) O(1) O(sqrt(n ...

  9. 绝对是全网最好的Splay 入门详解——洛谷P3369&BZOJ3224: Tyvj 1728 普通平衡树 包教包会

    平衡树是什么东西想必我就不用说太多了吧. 百度百科: 一个月之前的某天晚上,yuli巨佬为我们初步讲解了Splay,当时接触到了平衡树里的旋转等各种骚操作,感觉非常厉害.而第二天我调Splay的模板竟 ...

随机推荐

  1. lintcode-176-图中两个点之间的路线

    176-图中两个点之间的路线 给出一张有向图,设计一个算法判断两个点 s 与 t 之间是否存在路线. 样例 如下图: for s = B and t = E, return true for s = ...

  2. lintcode-16-带重复元素的排列

    带重复元素的排列 给出一个具有重复数字的列表,找出列表所有不同的排列. #### 样例 给出列表 [1,2,2],不同的排列有: [ [1,2,2], [2,1,2], [2,2,1] ] 挑战 使用 ...

  3. LintCode-211.字符串置换

    字符串置换 给定两个字符串,请设计一个方法来判定其中一个字符串是否为另一个字符串的置换. 置换的意思是,通过改变顺序可以使得两个字符串相等. 样例 "abc" 为 "cb ...

  4. LintCode-38.搜索二维矩阵 II

    搜索二维矩阵 II 写出一个高效的算法来搜索m×n矩阵中的值,返回这个值出现的次数. 这个矩阵具有以下特性: 每行中的整数从左到右是排序的. 每一列的整数从上到下是排序的. 在每一行或每一列中没有重复 ...

  5. mac mysql连接报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

    找了半天 又是kill进程,又是改设置文件,又是重启电脑,都不管用 翻到stackoverflow上的解决方案,实施成功: 原文链接:https://stackoverflow.com/questio ...

  6. 【Linux】- ps -ef |grep 命令

    ps:将某个进程显示出来 grep:查找 |:管道命令 表示ps命令与grep同时执行 PS是LINUX下最常用的也是非常强大的进程查看命令 grep命令是查找,是一种强大的文本搜索工具,它能使用正则 ...

  7. canvas drawImage 不显示

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Activiti5工作流笔记三

    组任务 直接指定办理人 流程图如下: import java.util.HashMap; import java.util.List; import java.util.Map; import org ...

  9. RT-thread-2.0.1移植(基于STM32F4xx)

    1.将下载的rt-thread-2.0.1解压后,得到如下图所示的文件列表. 在bsp目录下可以找到stm32f40x文件夹,这文件夹里面包括了库函数,其他芯片平台的文件夹统统删掉.在libcpu下, ...

  10. 复杂类型的write写入功能 步骤解析