並不對勁的splay

2022-05-08 20:36:15 字數 1670 閱讀 6488

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#include

#include

#include

#include

#include

#include

#define maxn 80001

#define inf 1ll<<32

#define mod 1000000

#define ll long long

using

namespace

std;

ll read()

ll n,f;

ll ans;

typedef

struct

node

tree;

struct

splay

inline

void

splay(ll u,ll k)

rot(u);

}if(k==0)root=u;

}inline

void

ins(ll k)

inline

void

fnd(ll k)

inline ll nxt_no_equ(ll k,ll f)

inline ll nxt_yes_equ(ll k,ll f)

inline

void

del(ll k)

void

start()

}t;int

main()

else

}f+=(x==1)?-1:1

; ans%=mod;

}cout

return0;

}

並不對勁的splay

並不對勁的費用流

最小費用最大流肯定要保證最大流,所以它和最大流有一些類似的性質。如果把費用看成邊,就可以每次走最短路 保證費用最小 走到不能走為止 保證最大流 費用流版的ek就是這樣。需要注意的是,反向弧的邊權為它對應的正向弧的費用的相反數,所以最短路要用spfa來求。費用流版的dinic,又叫zkw費用流,還是多...

並不對勁的字尾陣列

字尾陣列sa x 表示排序後第x位在排序前的位置。這個東西的求法有兩種,一種是倍增,時間複雜度o n log n 或o n log2n 另一種是用不知道什麼方法做到的o n 至於第二種方法是什麼,並不對勁的人並不知道,所以只說倍增。考慮正常地比較兩個字串,都是從頭比較到尾 那麼,如果把兩個字串都斷成...

並不對勁的卡常技巧

俗話說的好,心中有黨,常數極小。1 迴圈中加暫存器優化for register int i i n i 好像在開o2時這個沒什麼用。2 函式前inline int f int x 當呼叫函式本身的時間長度比執行函式的更長時效果會更顯著。配合read write 使用更佳。3 將取模運算改成if x ...