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. Leetcode 318.最大单词长度乘积

    最大单词长度乘积 . 示例 1: 输入: ["abcw","baz","foo","bar","xtfn&qu ...

  2. The 16th Zhejiang University Programming Contest-

    Handshakes Time Limit: 2 Seconds      Memory Limit: 65536 KB Last week, n students participated in t ...

  3. POJ 1201 差分方程分析

    POJ 1201 给你N个闭区间.每个区间分别为[ai,bi],你必须在这个区间上至少取ci个不同的整数. 现要求所有区间满足各自的条件. 问最少需要选多少个点. 例如[3,7](3)  [8,10] ...

  4. POJ3041:Asteroids【二分图匹配】

    二分图的最大匹配=最小顶点覆盖(Konig定理)=最大独立集的补集最大匹配经典的三种模型  这题就是最小顶点覆盖,顺便这题留给我的经验就是调试的时候一定要细心细心再细心对模板的各个细节都要熟!! #i ...

  5. 【NOIP模拟】数字对(RMQ,二分)

    题意:小H是个善于思考的学生,现在她又在思考一个有关序列的问题. 她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n). 这个特 ...

  6. Flex4分模块下样式动态加载步骤及相关问题的解决

    1.  给应用程序编写CSS文件 (1)在项目下创建CSS文件(任意路径,可以多个).本例在src下创建了5个样式文件 (2)Flex支持的CSS文件定义如下: a)  type selector(类 ...

  7. hihocoder 1873 ACM-ICPC北京赛区2018重现赛 D Frog and Portal

    http://hihocoder.com/problemset/problem/1873 时间限制:1000ms 单点时限:1000ms 内存限制:512MB 描述 A small frog want ...

  8. python执行

    转载:https://www.cnblogs.com/zflibra/p/4180796.html

  9. the attribute buffer size is too small 解决方法

    在进行查询的时候引发The attribute buffer size is too small错误解决 http://bbs.esrichina-bj.cn/esri/viewthread.php? ...

  10. grails的criteria和hql查询

    grails在查询方面也保留了hibernate的hql和criteria查询功能.hql自然不必多说基本不会有什么变化,grails的criteria查询在hibernate上面做了微调使用起来更加 ...