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. Activity生命周期 与 Activity 之间的通信

    一. Activity生命周期 上图 1. Activity状态 激活状态 : Activity出于前台 , 栈顶位置; 暂停状态 : 失去了焦点 , 但是用户仍然可以看到 , 比如弹出一个对话框 , ...

  2. LintCode-12.带最小值操作的栈

    带最小值操作的栈 实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值. 你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成. 注意事项 如果堆栈中 ...

  3. server2003 必要的系统优化和安全设置

    修改远程桌面端口: Windows 2003系统中的远程终端服务是一项功能非常强大的服务,同时也成了入侵者长驻主机的通道,入侵者可以利用一些手段得到管理员账号和密码并入侵主机.下面,我们来看看如何通过 ...

  4. CSS设计指南之CSS三种机制:继承、层叠和特指

    一.继承 CSS中的祖先元素也会向后代传递一样东西:CSS属性的值.body元素是所有元素的祖先,所有标签都是它的后代,比如为body元素设置一种字体,那么文档中的所有元素,无论它在层次结构中多么靠下 ...

  5. dedecms给原模型添加新字段

    1.进入dedecms后台 2.点击核心=>频道模型=>内容模型管理(在这里可以看到dedecms预设的模型设置) 3.选中我们需要的模型,点击更改,跳入以下页面 4.点击字段管理(可以看 ...

  6. google go语言开发

    C:cd C:\Program Files\go\gopath\src\opmsset GOOS=linuxset GOARCH=amd64set CGO_ENABLED=0make.batgo in ...

  7. 累积下学习 C#时和 Java时的不同点

    ==和equals()方法的区别: 首先有一个观点: 这两个都是用来比较值是否相等的 ( 这里的值有时候指的是地址值, 有时候是存储的值; 下面将地址值称为地址, 存储的值称为值 ) 在Java中: ...

  8. Linux中实现在系统启动时自动加载模块

    下面是以前学习Linux时写的,后来仔细研究rc.sysinit后发现,只需要修改下列地方就可以了,不必这么麻烦的: rc.sysinit中有这样的一段代码: # Load other user-de ...

  9. Oracle 以某字段分组,以某字段排序,取前几条

    select * from (select row_number() over(partition by 以此字段为分组  order by 以此字段排序 desc rn from dual) whe ...

  10. 【国家集训队】聪聪可可 ——树形DP

    感觉是一道很妙的树形DP题,充分利用到了树的性质(虽然说点分治也可以做,,,,但是本蒟蒻不会啊) 然而某Twilight_Sx大佬表示这道题真的非常水,,,本蒟蒻也只能瑟瑟发抖了 本蒟蒻表示还是要经过 ...