Tyvj 1728 普通平衡樹

2022-05-01 05:45:12 字數 3193 閱讀 9883

time limit: 10 sec  memory limit: 128 mb

submit: 13242  solved: 5675

[submit][status][discuss]

您需要寫一種資料結構(可參考題目標題),來維護一些數,其中需要提供以下操作:

1. 插入x數

2. 刪除x數(若有多個相同的數,因只刪除乙個)

3. 查詢x數的排名(若有多個相同的數,因輸出最小的排名)

4. 查詢排名為x的數

5. 求x的前驅(前驅定義為小於x,且最大的數)

6. 求x的後繼(後繼定義為大於x,且最小的數)

第一行為n,表示操作的個數,下面n行每行有兩個數opt和x,opt表示操作的序號(1<=opt<=6)

對於操作3,4,5,6每行輸出乙個數,表示對應答案

101 106465

4 11 317721

1 460929

1 644985

1 84185

1 89851

6 81968

1 492737

5 493598

106465

84185

492737

1.n的資料範圍:n<=100000

2.每個數的資料範圍:[-2e9,2e9]

平衡樹

splay

事實上,哨兵還是挺有用的,減輕邏輯負擔;

由於是模板題:

t節點數值,f節點父親編號,sz以節點為根的子樹尺寸,am節點中數的個數,s節點的左右子編號;

rot()單旋;

splay()伸展(這裡沒有用雙旋,因為腦模單旋和雙旋操作量和結果一樣,實測雙旋也並不比單旋快);

//我可能跟我師傅學了假的雙旋,對於單側鏈的操作和單旋一致,故而沒有任何優化效果,所以和這位大佬學吧,**splay的雙旋;

//好吧,可能是題目,實測雙旋有很強的優化效果;

ins()新增數;

find1()把要查詢的節點旋到樹根;

find2()查詢序號對應節點;

find3()查詢前驅;

find4()查詢後繼;

del()刪除數;

del():減少root節點的am值或是刪除root節點;

case1:減少root節點的sz和am值並退出;

case2:

將root的右子樹接到root的左子樹中的最右子上,同時更新從root的左子樹到左子樹樹中最右子的路徑上的節點的sz值;

調整嫁接處的值,root改為原root的左子;

將原root的左子樹的最右子旋到根的位置;

1 #include2

const

int maxn=3e5;

3int

n,ope,val;

4int

rt,hd;

5int t[maxn],f[maxn],sz[maxn],am[maxn],s[maxn][2];6

void rot(int

x)14 f[x]=z,f[y]=x,f[s[x][r]]=y;

15 s[y][l]=s[x][r],s[x][r]=y;

16 sz[y]=sz[s[y][0]]+sz[s[y][1]]+am[y];

17 sz[x]=sz[s[x][0]]+sz[s[x][1]]+am[x];18}

19void splay(int x)

20void ins(int k,int x,int

fa)22

while(k) fa=k,++sz[k],k=s[k][x>t[k]];

23 k=s[fa][x>t[fa]]=++hd;

24 t[k]=x,sz[k]=1,f[k]=fa,am[k]++;

25splay(k);26}

27void find1(int k,int

x)32

int find2(int k,int

x)37

int find3(int k,int x,int

sum)

42int find4(int k,int x,int

sum)

47void del(int k,int

x)49 x=s[k][1

];50

while(s[x][0]) x=s[x][0],sz[x]+=sz[s[k][0

]];51 f[s[k][0]]=x,s[x][0]=s[k][0],rt=s[k][1

];52 f[rt]=0;53

splay(x);54}

55int

main()

69return0;

70 }

1.0又重新寫了一遍,先手模了幾棵二叉查詢樹,直觀地認識了一下雙旋對樹結構的影響(對於「之」字形圖,比較容易看出雙旋的優越性);

然後,優化了一下邏輯,給出了正確的雙旋,使**更加美觀,跑的也稍快了。

1 #include2

const

int maxn=1e5+10;3

intrt,ts;

4int

t[maxn],sz[maxn],num[maxn];

5int f[maxn],s[maxn][2];6

void rot(int

x)15

void splay(int

x)24}25

}26void ins(int k,int

x)34

splay(k);35}

36void del(int k,int

x)46}47

int query(int k,int

x)52

int search(int k,int

x)57

int in_x(int k,int x,int

now)

63else

return in_x(s[k][0

],x,now);64}

65int ax_x(int k,int x,int

now)

71else

return ax_x(s[k][1

],x,now);72}

73int

n,opt,x;

74int

main()

86return0;

87 }

Tyvj 1728 普通平衡樹

hysbz 3224 tyvj 1728 普通平衡樹 time limit 10000ms memory limit 131072kb 64bit io format lld llu submit status use mathjax to parse formulas description 您需...

Tyvj 1728 普通平衡樹

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

3224 Tyvj 1728 普通平衡樹

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