伸展樹splay學習小記

2021-07-14 05:09:23 字數 3720 閱讀 5445

splay是基本操作,rotate是splay的基本操作。splay(now,root)把now splay到root的下面。單旋和雙旋就不說了。我們可以簡化操作,如果是一字型(方向相同)則先旋father,否則先旋now。然後再旋now。

rotate now是指將now繞father rotate。有兩個方向,表示now是father的左兒子還是右兒子。

bool flag(int

now)

通過方向標記,我們可以將兩個方向的rotate合成乙個。
void rotate(int now)
具體步驟請自行腦補。

別忘了rotate完成後要updata。

void updata(int

pos)

int kth(int

now,int th)

int pre(int

val)

int succ(int

val)

首先要找到乙個合適的位置
int getpos(int

now,int val)

但是我們並不能保證這個點是大於還是小於插入節點
void insert(int root,int

pos,int val)

int tmp=son[root][0];key[pos]=val;

son[root][0]=pos;father[pos]=root;

son[pos][0]=tmp;father[tmp]=pos;

updata(pos);updata(root);

splay(pos,0);

}

我們把剛好比插入點大的點作為根,在左子樹插入。如果根小於插入點,則要將根的後繼變成根(!!!注意不是根的右兒子!!!)

至此splay的基本操作我們都完成了。

對於有重複元素的題,我們必須小心小心再小心。find的時候必須找最小序號的哪乙個,pre和succ查詢的數可能不在splay中,要做一點處理。

void

dele(int

root,int

val)

int rank(int

now,int val)

int find(int now,int val)
#include

#include#include#include#include#define fo(i,j,k) for(int i=j;i<=k;i++)

#define fd(i,j,k) for(int i=j;i>=k;i--)

using namespace std;

intconst maxn=1000000,inf=2147483647;

int n,size[maxn+10],key[maxn+10],father[maxn+10],son[maxn+10][10];

void updata(int pos)

bool flag(int

now)

void rotate(int

now)

void splay(int

now,int root)

rotate(now);

}}int getpos(int

now,int val)

int kth(int

now,int th)

int pre(int val)

int succ(int val)

void insert(int root,int pos,int val)

int tmp=son[root][0];key[pos]=val;

son[root][0]=pos;father[pos]=root;

son[pos][0]=tmp;father[tmp]=pos;

updata(pos);updata(root);

splay(pos,0);

}int main()

printf("%d\n",ans);

return 0;

}

#include

#include

#include

#include

#include

#define fo(i,j,k) for(int i=j;i<=k;i++)

#define fd(i,j,k) for(int i=j;i>=k;i--)

using

namespace

std;

intconst maxn=100000,inf=2147483647;

int n,key[maxn+10],mx[maxn+10],mi[maxn+10],size[maxn+10],father[maxn+10],son[maxn+10][10];

bool flag(int now)

void updata(int now)

void rotate(int now)

void splay(int now,int root)

}int find(int now,int val)

int kth(int now,int val)

int succ(int now)

void insert(int root,int pos,int val)

key[pos]=val;int tmp=son[root][0];

son[root][0]=pos;father[pos]=root;

son[pos][0]=tmp;father[tmp]=pos;

updata(pos);updata(root);

}int pre(int now)

void dele(int root,int val)

int rank(int now,int val)

int main()

else

if(opt==4)

else

if(opt==5)

else

}return

0;}

總結 伸展樹Splay

感覺我在聯賽還差4天的時候學習splay有點慌,但還是要學一下。我們先對splay的陣列進行一些定義 struct nodet n 2 我們的splay應該要支援以下幾個操作 如下 includeusing namespace std const int n 500010 int root,tot ...

學習筆記第六節 伸展樹splay

正文 說到伸展樹,大家想到的可能是複雜,冗長,很容易打錯,思路卻很好理解。沒錯,伸展樹的確是這麼乙個東西,如果你做多了題,學會用它之後,你就會覺得很得心應手,輕鬆面對許多高階資料結構題。這個當然也是乙個鍛鍊人的耐心的東西,有乙份 調了4天emm。伸展樹是一棵二叉搜尋樹,就是說,它是一棵單一關鍵字排序...

資料結構 Splay伸展樹 普通平衡樹

題目描述 您需要寫一種資料結構 可參考題目標題 來維護一些數,其中需要提供以下操作 插入x數 刪除x數 若有多個相同的數,因只刪除乙個 查詢x數的排名 若有多個相同的數,因輸出最小的排名 查詢排名為x的數 求x的前驅 前驅定義為小於x,且最大的數 求x的後繼 後繼定義為大於x,且最小的數 輸入 第一...