splay是基本操作,rotate是splay的基本操作。splay(now,root)把now splay到root的下面。單旋和雙旋就不說了。我們可以簡化操作,如果是一字型(方向相同)則先旋father,否則先旋now。然後再旋now。
rotate now是指將now繞father rotate。有兩個方向,表示now是father的左兒子還是右兒子。
通過方向標記,我們可以將兩個方向的rotate合成乙個。bool flag(int
now)
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,且最小的數 輸入 第一...