題解 ZJOI2006 書架

2022-06-08 08:39:09 字數 1601 閱讀 9409

link

小 t 有乙個很大的書櫃。這個書櫃的構造有些獨特,即書櫃裡的書是從上至下堆放成一列。她用 \(1\) 到 \(n\) 的正整數給每本書都編了號。

小 t 在看書的時候,每次取出一本書,看完後放回書櫃然後再拿下一本。由於這些書太有吸引力了,所以她看完後常常會忘記原來是放在書櫃的什麼位置。不過小 t 的記憶力是非常好的,所以每次放書的時候至少能夠將那本書放在拿出來時的位置附近,比如說她拿的時候這本書上面有 \(x\) 本書,那麼放回去時這本書上面就只可能有 \(x−1\)、\(x\)或 \(x+1\) 本書。

當然也有特殊情況,比如在看書的時候突然**響了或者有朋友來訪。這時候粗心的小 t 會隨手把書放在書櫃裡所有書的最上面或者最下面,然後轉身離開。

久而久之,小 t 的書櫃裡的書的順序就會越來越亂,找到特定的編號的書就變得越來越困難。於是她想請你幫她編寫乙個圖書管理程式,處理她看書時的一些操作,以及回答她的兩個提問:

這道題的難點在於如何把編號和位置聯絡起來。支援乙個根據編號找位置的操作。

這裡令每本書的編號為權值,每本書的位置為排名

首先要把每個點權(\(x\))初始對應的編號(放在樹里的,就是\(tot\))記錄下來。

\(pos[x]=tot\)

並維護樹上結點的父親節點(馬上解釋為什麼)

每查詢乙個權值,就先把它的初始編號取出來,根據初始編號一直往上跳,

初始排名為自己的左子樹大小+1

兩種情況:

它是父親的右兒子:它的排名要加上它父親的左兒子的\(size\) ,然後往上跳

它是父親的左兒子:排名不變,往上跳

跳到根節點,返回排名(此權值的位置)

能夠由編號得到位置,問題也就解決了大半(≧▽≦)/啦啦啦

找到前驅/後繼交換位置時要精準。

以\(t==-1\)為例:

new1,new2表示合併順序

得到位置後記得減\(1\)

這裡直接給的位置,不用把\(pos[s]\)取出來了!!!

#include#define n (160010)

using namespace std;

struct xbkt[n];

int n,m,tot,rt,pos[n];

string opt;

inline int read()

while(ch>='0'&&ch<='9')

return f?-w:w;

}inline void update(int p)

inline int new(int val)

inline void split(int p,int k,int &a,int &b)

if(opt[0]=='b')

if(opt[0]=='i')

if(f==-1)

} if(opt[0]=='a')

if(opt[0]=='q')

} return 0;

}

ZJOI2006 書架 平衡樹

題目描述 小t有乙個很大的書櫃。這個書櫃的構造有些獨特,即書櫃裡的書是從上至下堆放成一列。她用1到n的正整數給每本書都編了號。小t在看書的時候,每次取出一本書,看完後放回書櫃然後再拿下一本。由於這些書太有吸引力了,所以她看完後常常會忘記原來是放在書櫃的什麼位置。不過小t的記憶力是非常好的,所以每次放...

ZJOI2006 書架(樹狀陣列水過)

這道題顯然平衡樹,splay,treap什麼的隨便切 然而我不想打,決定水過這道題 把空間開3倍,樹狀陣列維護它前面的樹的個數,開個id陣列記錄位置 找乙個數排名直接二分加求字首和,log 2的搞一搞 把乙個數放在頂 低 直接丟在當前頂 低的前後就可以了不然開3倍陣列幹嘛 c常數小堪比log的平衡樹...

P2596 ZJOI2006 書架 題解

最近學習了splay和非旋式treap,於是找到了這道題。維護乙個序列,支援移動元素,查詢元素在序列中的位置,查詢序列中某乙個位置的元素。無旋式treap可以維護一棵樹的中序遍歷結果,但是不支援通過編號來找節點。於是在無旋式treap的基礎上,維護每個節點的父親,這樣就可以求出元素在序列中的位置。對...