省選將至,慌得一批,hale趕緊去學了學splay,防止被打爆,雖說一定會被打爆的
不過這玩意是真的噁心,hale花了三個中午去搞掉他
一點點自己的理解啦,嚶嚶嚶
emmm,廢話少說進入正題
一 。啥是平衡樹?
平衡樹,即平衡二叉樹(balanced binary tree),具有以下性質:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。
嗯,說得很好,我也知道他很好啊,哼唧唧、
二。平衡樹可以幹什麼?
通過不斷調整自身平衡來不使自身退化成鏈,以便於操作,比如查詢前驅後繼,插入乙個數,刪除乙個數,查詢排名為k的數
先解釋一下變數名
structnode
t[n];
操作集合如下
1。push_up操作,
其實我也不知道給他取什麼名字了,比較線段樹的同名操作也就不難理解了
void push_up(intu)
2。左右旋轉操作,這裡的話可以參見別人的博克去理解哦 主要是我真的講不好這個東西
但是我這個旋轉碼量小,可以作為參考而且也挺快的
void rotate(intx)void splay(int x,int goal)//
當前點,目標點
if (goal==0) root=x;
}
三。插入乙個數
void insert(int x)//插入乙個x的數
if (u) t[u].cnt++;//
如果存在就直接記錄個數
else
//不然就重新開點
splay(u,
0);//
將點旋上去,保持樹的平衡
}
四。查詢乙個數
void find(intx)
五。查詢前驅後驅
int next(int x,intf)
六。刪除乙個數
void delete(intx)
else t[next].ch[0]=0;//
不然直接斷掉
}
七。查詢第k小數
int k_th(intx)
else
if (t[y].son>=x) u=y;//
不然在當前區間查詢
else
return t[u].val;//
否則就找到啦
}}
好了,區間翻轉的坑回頭再填了,會很快的,最近作業太多了
hale要加油了,接下來放出**
#includeusingnamespace
std;
intm,n,k,p,root,cnt,tot,opt;
const
int n=2e6+6
;struct
node
t[n];
void push_up(int
u)void rotate(int
x)void splay(int x,int
goal)
if (goal==0) root=x;
}void insert(int
x)
if (u) t[u].cnt++;
else
splay(u,
0);
}void find(int
x)int next(int x,int
f)void delete(int
x)
else t[next].ch[0]=0; }
int k_th(int
x)
else
if (t[y].son>=x) u=y;
else
return
t[u].val;
}}int
main()
if (opt==2
)
if (opt==3)
if (opt==4)
if (opt==5)
if (opt==6)
} return0;
}
splay 學習筆記
核心函式splay 每次訪問乙個節點,都把該節點轉到根 包括插入 查詢 操作 思想 對於訪問頻率較高的節點,使其處於根節點附近,從而保證log複雜度 splay可以維護中序遍歷是有序序列 也可維護 中序遍歷是當前操作後的序列 const int n 1e5 10 struct nodet n int...
Splay學習筆記
一種二叉樹的樹形資料結構,其定義如下 一種自平衡二叉搜尋樹,通過不斷將某個節點旋轉到根節點,使得整棵樹仍然滿足二叉查詢樹的性質,且保持平衡而不至於退化為鏈 root tot fa i child i 0 1 val i cnt i size i 根節點節點總數 父親左右兒子 點權出現次數 子樹大小 ...
Splay學習筆記
n n 500000 個數,要求維護區間加,區間查詢 很簡單,用線段樹 樹狀陣列隨便寫寫就能過 n n 500000 個數,維護插入 刪除 找區間第k大 小 用平衡樹 set也能過 n n 500000 個數,維護區間翻轉,區間查詢,插入,刪除 這個時候就需要用到伸展樹 splay splay是一種...