冬令营被平衡树坑了之后,打算苦练一番数据结构(QAQ)。

先是打了一下想学好久的替罪羊树。

替罪羊树实现方法很简单,就是在不满足平衡条件的时候暴力重构子树。

调试小结:

  1.删除操作分两类情况:如果某点只有一个孩子,将它的孩子提上来即可,否则将它变为它的前驱,再删去它的前驱。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const double a=0.75;
inline int getnum()
{
int ans=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh*=-;ch=getchar();}
while(ch>=''&&ch<='')ans=ans*+ch-'',ch=getchar();
return fh*ans;
}
struct node{int s[],f,size,num;}t[];int tnum,root;
inline void init()
{
tnum=;root=;
t[].num=-;t[].size=;t[].s[]=;
t[].num=;t[].size=;t[].f=;
}
inline bool balance(int po)
{
return (double)t[po].size*a>=(double)t[t[po].s[]].size
&&(double)t[po].size*a>=(double)t[t[po].s[]].size;
}
int E[],esize;
void travel(int po)
{
if(t[po].s[])travel(t[po].s[]);
E[++esize]=po;
if(t[po].s[])travel(t[po].s[]);
}
int build(int l,int r)
{
if(l>r)return ;
int mid=(l+r)/,po=E[mid];
t[t[po].s[]=build(l,mid-)].f=po;
t[t[po].s[]=build(mid+,r)].f=po;
t[po].size=t[t[po].s[]].size+t[t[po].s[]].size+;
return po;
}
inline void rebuild(int po)
{
esize=;travel(po);
int fa=t[po].f,ws=(t[t[po].f].s[]==po);
int npo=build(,esize);
t[t[fa].s[ws]=npo].f=fa;
if(po==root)root=npo;
}
inline void insert(int num)
{
int now=root,npo=++tnum;
t[npo].size=;t[npo].num=num;
while(true)
{
t[now].size++;
bool ws=(num>=t[now].num);
if(t[now].s[ws])now=t[now].s[ws];
else {t[t[now].s[ws]=npo].f=now;break ;}
}
int inv=;
for(int i=npo;i;i=t[i].f)if(!balance(i))inv=i;
if(inv)rebuild(inv);
}
inline int rank(int num)
{
int now=root,ans=;
while(now)
{
if(t[now].num<num)ans+=t[t[now].s[]].size+,now=t[now].s[];
else now=t[now].s[];
}
return ans;
}
inline int getkth(int kth)
{
int now=root;
while(true)
{
if(t[t[now].s[]].size==kth-)return now;
else if(t[t[now].s[]].size>=kth)now=t[now].s[];
else kth-=t[t[now].s[]].size+,now=t[now].s[];
}
return now;
}
inline int getn(int num)
{
int now=root;
while(true)
{
if(t[now].num==num)return now;
else now=t[now].s[t[now].num<num];
}
}
inline void erase(int po)
{
if(t[po].s[]&&t[po].s[])
{
int tpo=t[po].s[];
while(t[tpo].s[])tpo=t[tpo].s[];
t[po].num=t[tpo].num;
po=tpo;
}
int son=(t[po].s[])?t[po].s[]:t[po].s[],ws=(t[t[po].f].s[]==po);
t[t[t[po].f].s[ws]=son].f=t[po].f;
for(int i=t[po].f;i;i=t[i].f)t[i].size--;
if(po==root)root=son;
}
inline int succ(int num)
{
int now=root,ans=;
while(now)
{
if(t[now].num>num)ans=min(ans,t[now].num),now=t[now].s[];
else now=t[now].s[];
}
return ans;
}
inline int pred(int num)
{
int now=root,ans=-;
while(now)
{
if(t[now].num<num)ans=max(ans,t[now].num),now=t[now].s[];
else now=t[now].s[];
}
return ans;
}
int main(int argc, char *argv[])
{
init();
int n=getnum();
for(int i=;i<=n;i++)
{
int p=getnum(),num=getnum();
if(p==)insert(num);
if(p==)erase(getn(num));
if(p==)printf("%d\n",rank(num));
if(p==)printf("%d\n",t[getkth(num+)].num);
if(p==)printf("%d\n",pred(num));
if(p==)printf("%d\n",succ(num));
}
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 普通平衡树(名次树+处理相同)

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

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

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

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

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

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

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

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

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

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

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

  9. [BZOJ3224] [Tyvj 1728] 普通平衡树 (treap)

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相 ...

随机推荐

  1. Redis——分布式简单使用

    Redis简介:Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. Redis安装:参考博客http://www ...

  2. 如何在VMWare Workstation实现虚拟机与真机的文件共享

    1.进入虚拟机的配置选项 进入方法有三种,一种是使用快捷键Ctrl+D,第二种是先右键点击虚拟机再选择Settings选项,第三种是点击快捷栏中的VM后选择Settings选项,后两种方法的截图如下. ...

  3. php 字符串的一些操作,以便记忆

    php 字符串的操作 trim($str,'特殊字符')-----去除字符串左右两边的字符,返回字符串 ltrim(),rtrim()--------------------左,由两边,与trim() ...

  4. SQLHelper---赵晓虎(简洁,全面)

    public static class SQLHelper { //获取连接字符串,,首先添加对configuration的引用 private static string connStr = Con ...

  5. Java算法-快速排序

    快速排序也是用归并方法实现的一个“分而治之”的排序算法,它的魅力之处在于它能在每次partition(排序算法的核心所在)都能为一个数组元素确定其排序最终正确位置(一次就定位准,下次循环就不考虑这个元 ...

  6. 【CodeForces 622A】Infinite Sequence

    题意 一个序列是, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5....这样排的,求第n个是什么数字. 分析 第n个位置属于1到k,求出k,然后n-i*(i-1)/ ...

  7. python 学习笔记3(循环方式;list初始化;循环对象/生成器/表推导;函数对象;异常处理)

    ### Python的强大很大一部分原因在于,它提供有很多已经写好的,可以现成用的对象 16. 循环方式笔记: 1)range(0, 8, 2)   #(上限,下限,步长)  可以实现对元素或者下标的 ...

  8. word中打出希腊字母

    作为一个键盘党,不喜欢用鼠标去选择希腊字母,希望只用键盘就能在word中打出希腊字母. 方法是:按照下图所示对应表,先输入英文字母,然后选中它并按Ctrl+Shift+Q

  9. NOI题库 09:图像旋转翻转变换

    NOI题库开始的题,也是略水,当然也是大水,所以彼此彼此 09:图像旋转翻转变换 总时间限制: 1000ms 内存限制: 65536kB 描述 给定m行n列的图像各像素点灰度值,对其依次进行一系列操作 ...

  10. 【poj2546】 Circular Area

    http://poj.org/problem?id=2546 (题目链接) 题意 求两圆的面积交 Solution 一道水题Wa死我了,肯定是昨晚搞太晚的缘故= =. 两圆的位置关系有5种,而这里要求 ...