splay和不加任何旋转一定会被卡的二叉搜索树的唯一区别就是每次操作把当前节点旋转到根。

旋转有各种zig、zag的组合方式,感觉很麻烦,并不对劲的人并不想讲。

其实可以找出一些共性将它们合并。设ls(a)=[点a是其父亲的左儿子],son[a][0]=a的左儿子,son[a][1]=a的右儿子,fa[a]=a的父亲。会发现单旋u时,有变动的点只有son[u][ls(u)^1],u,fa[u],fa[fa[u]]。再仔细想想,儿子有变动的有fa[fa[u]](son[fa[fa[u]]][ls(fa[u])]=u)、fa[u](son[fa[u]][ls(u)]=son[u][ls(u)^1])、u(son[u][ls(u)^1]=fa[u]),父亲有变化的是fa[u](fa[fa[u]]=u)、u(fa[u]=fa[fa[u]])、son[u][ls(u)^1](fa[son[u][ls(u)^1]=fa[u])。都有三组,好记(可能吧…)又好写。

而当双旋u时,若u,fa[u],fa[fa[u]]不共线(即ls(u)^ls(fa[u])==1),则先单旋u,再单旋u;反之,则先单旋fa[u],再单旋u。每次旋转如果深度不小于2就双旋,否则单旋。这样写起来就会很容易了。

根据刚刚的旋转方法,可以看出每次被旋转到根的节点至多经历一次单旋。

至于时间复杂度,在刚学splay时就觉得它很不靠谱,因为感觉每次把某个节点旋转到根并不能缩短多少时间。后来发现每次操作总会进行很多次双旋,双旋总能让这个树变的和你想象中不太一样。

至于严格证明什么的,还是交给手健康的人手推吧,这里并不是对劲的splay。

例题:洛谷2286 [HNOI2004]宠物收养场

并不觉得这题有什么好说的。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<cstdlib>
#define maxn 80001
#define inf 1ll<<32
#define mod 1000000
#define ll long long
using namespace std;
ll read(){
ll x=,f=;
char ch=getchar();
while(isdigit(ch)== && ch!='-')ch=getchar();
if(ch=='-')f=-;
while(isdigit(ch))x=x*+ch-'',ch=getchar();
return x*f;
}
ll n,f;
ll ans;
typedef struct node
{
ll son[],fa;//0左,1右
ll key;
}Tree;
struct Splay
{
ll cnt,root;
Tree x[maxn];
inline void rot(ll u){
ll fu=x[u].fa,ffu=x[fu].fa,l=(x[fu].son[]==u),r=l^;
ll l2=(fu==x[ffu].son[]);
x[ffu].son[l2]=u;
x[u].fa=ffu;
x[fu].fa=u;
x[fu].son[l]=x[u].son[r];
x[x[u].son[r]].fa=fu;
x[u].son[r]=fu;
}
inline void splay(ll u,ll k){
while(x[u].fa!=k){
ll fu=x[u].fa,ffu=x[fu].fa;
if(ffu!=k){
if((x[ffu].son[]==x[u].fa)^(x[fu].son[]==u))
rot(u);
else rot(fu);
}
rot(u);
}
if(k==)root=u;
}
inline void ins(ll k){
ll lk=nxt_no_equ(k,),
rk=nxt_no_equ(k,);
splay(lk,),splay(rk,lk);
x[rk].son[]=++cnt;
x[cnt].fa=rk,x[cnt].son[]=x[cnt].son[]=,x[cnt].key=k;
splay(cnt,);
}
inline void fnd(ll k){
ll u=root;
if(u==)return;
while(x[u].son[k>x[u].key] && k!=x[u].key)
u=x[u].son[k>x[u].key];
splay(u,);
}
inline ll nxt_no_equ(ll k,ll f){//f==1 bigger
fnd(k);
ll u=root;
if(x[u].key>k && f)return u;
if(x[u].key<k && f==)return u;
u=x[u].son[f];
while(x[u].son[f^])u=x[u].son[f^];
return u;
}
inline ll nxt_yes_equ(ll k,ll f){
fnd(k);
ll u=root;
if(x[u].key>=k && f)return u;
if(x[u].key<=k && f==)return u;
u=x[u].son[f];
while(x[u].son[f^])u=x[u].son[f^];
return u;
}
inline void del(ll k){
ll lk=nxt_no_equ(k,),
rk=nxt_no_equ(k,);
splay(lk,),splay(rk,lk);
x[rk].son[]=;
}
void start(){
cnt=;
root=;
ins(inf);ins(-inf);
}
}t;
int main()
{
n=read();
t.start();
for(ll i=;i<=n;i++)
{// x,f=0 pet , x,f=1 people
ll x=read(),y=read();
if(f==){
t.ins(y);
}
else{
if(x==(f<))t.ins(y);
else{
ll lt=t.x[t.nxt_no_equ(y,)].key,
rt=t.x[t.nxt_no_equ(y,)].key,
ttt=abs(lt-y)<=abs(rt-y)?lt:rt;
ans+=abs(ttt-y);
t.del(ttt);
}
}
f+=(x==)?-:;
ans%=mod;
}
cout<<ans%mod;
return ;
}

并不对劲的splay

并不对劲的splay的更多相关文章

  1. 并不对劲的bzoj1861: [Zjoi2006]Book 书架

    传送门-> 这题的正确做法是splay维护这摞书. 但是并不对劲的人选择了暴力(皮这一下很开心). #include<algorithm> #include<cmath> ...

  2. 并不对劲的bzoj1500: [NOI2005]维修数列

    传送门-> 这题没什么好说的……小清新数据结构题……并不对劲的人太菜了,之前照着标程逐行比对才过了这道题,前几天刚刚把这题一遍写对…… 其实这题应该口胡很容易.操作1,2,3,4,5就是普通的s ...

  3. 并不对劲的fhq treap

    听说很对劲的太刀流不止会splay一种平衡树,并不对劲的片手流为了反驳他,并与之针锋相对,决定学学高端操作. 很对劲的太刀流-> 据说splay常数极大,但是由于只知道splay一种平衡树能对序 ...

  4. 并不对劲的LCT

    LCT,是连猫树(link-cat-tree)的缩写.它是树链剖分和splay的结合版本. 由于有很多关于LCT的文章以及这并不是对劲的文章,并不对劲的人并不打算讲得太详细. 推荐:详细的LCT-&g ...

  5. BZOJ 1251: 序列终结者 [splay]

    1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3778  Solved: 1583[Submit][Status][Discu ...

  6. [bzoj1269][AHOI2006文本编辑器editor] (splay模版题 or pb_ds [rope]大法)

    Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或 ...

  7. splay最终模板

    来自wjmzbmr的splay模板 #include<cstdio> #include<iostream> #include<algorithm> using na ...

  8. bzoj 3506 && bzoj 1552 splay

    查最小值,删除,翻转... 显然splay啊... #include<iostream> #include<cstdio> #include<algorithm> ...

  9. 【splay】文艺平衡树 BZOJ 3223

    Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3  ...

随机推荐

  1. The more, The Better(树形DP)

    Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有 ...

  2. hihoCoder#1141 二分·归并排序之逆序对

    原题地址 又是一道WA成狗的题,最后发现原来是结果溢出了.. 代码: #include <iostream> #include <cstring> using namespac ...

  3. [codeforces551E]GukiZ and GukiZiana

    [codeforces551E]GukiZ and GukiZiana 试题描述 Professor GukiZ was playing with arrays again and accidenta ...

  4. centos 6.5 yum安装lnmp

    转自:http://blog.csdn.net/lane_l/article/details/20235909 准备篇: 端口 vi /etc/sysconfig/iptables -A INPUT ...

  5. PHP 常见问题3

    1,Http 和 Https 的区别 第一:http 是超文本传输协议,信息是明文传输,https 是具有安全性的 ssl 加密传输协议 第二:http 和 https 使用的是完全不同的连接方式,端 ...

  6. JAVA实验--统计文章中单词的个数并排序

    分析: 1)要统计单词的个数,就自己的对文章中单词出现的判断的理解来说是:当出现一个非字母的字符的时候,对前面的一部分字符串归结为单词 2)对于最后要判断字母出现的个数这个问题,我认为应该是要用到ma ...

  7. Eclipse打war包方法以及Eclipse移植项目时JDK版本不匹配Project facet Java version 1.7 is not supported

    打包时: 在项目上右键选择Export,如图: 然后选择WAR file,如图所示.接着再:其中web projecct为打出来包的名字, Destination,打包后存的位置,点击Browse.. ...

  8. java去空格

    1.trim()是去掉首尾空格    2.str.replace(" ", ""); 去掉所有空格,包括首尾.中间    3.或者replaceAll(&quo ...

  9. java native interface JNI 调用Java方法

    在上一篇文章中介绍了JNI.以及java调用JNI.这篇讲一下 JNI调用java方法. 通过使用合适的JNI函数,你能够创建Java对象,get.set 静态(static)和 实例(instanc ...

  10. coco2d-js demo程序之滚动的小球

    近期有一个游戏叫围住神经猫,报道说是使用html5技术来做的. html5的跨平台的优良特性非常不错.对于人手不足,技术不足,选用html5技术实现跨平台的梦想真是不错. 近期在看coco2d-js这 ...