1. 程式人生 > >【NEW】[平衡樹]模板而已

【NEW】[平衡樹]模板而已

題目描述

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

插入 x 數
刪除 x 數(若有多個相同的數,因只刪除一個)
查詢 x 數的排名(排名定義為比當前數小的數的個數 +1。若有多個相同的數,因輸出最小的排名)
查詢排名為 x 的數
求 x 的前驅(前驅定義為小於 x,且最大的數)
求 x 的後繼(後繼定義為大於 x,且最小的數)
輸入輸出格式

輸入格式:
第一行為n,表示操作的個數,下面n行每行有兩個數opt和x,opt表示操作的序號( 1≤opt≤6)

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

輸入輸出樣例

輸入樣例

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

輸出樣例

106465
84185
492737
說明

時空限制:1000ms,128M

來源:Tyvj1728 原名:普通平衡樹

分析

就是平衡樹
3注意:
1、能寫else就用else,因為&地址操作符會使變數在兩條先後的if語句中可能都能進入(即使條件完全相反)
2、左旋旋的是右兒子節點(右旋同理)
3、標總是對的,別去質疑
滑稽

#include <iostream>
#include <cstdio> #include <ctime> #include <cstdlib> #define rep(i,a,b) for (i=a;i<=b;i++) using namespace std; struct node { int l,r; int key,data,size; }t[100001]; int tcnt=0,rt=0; void UPDATE(int x) { t[x].size=t[t[x].r].size+t[t[x].l].size+1; } void RIGHT_ROTATE(int
&x) { int y=t[x].l; t[x].l=t[y].r;t[y].r=x; UPDATE(x);UPDATE(y); x=y; } void LEFT_ROTATE(int &x) { int y=t[x].r; t[x].r=t[y].l;t[y].l=x; UPDATE(x);UPDATE(y); x=y; } void INSERT(int &x,int insdata) { if (x==0) { x=++tcnt; t[x].size=1; t[x].data=insdata; t[x].key=rand(); return; } if (insdata<=t[x].data) { INSERT(t[x].l,insdata); if (t[t[x].l].key>t[x].key) RIGHT_ROTATE(x); } else { INSERT(t[x].r,insdata); if (t[t[x].r].key>t[x].key) LEFT_ROTATE(x); } UPDATE(x); } int GET_RANK(int x,int k) { if (x==0) return 0; if (k>t[x].data) return t[t[x].l].size+GET_RANK(t[x].r,k)+1; else return GET_RANK(t[x].l,k); } int GET_DATA(int x,int k) { if (t[t[x].l].size+1==k) return t[x].data; if (k<t[t[x].l].size+1) return GET_DATA(t[x].l,k); else return GET_DATA(t[x].r,k-(t[t[x].l].size+1)); } int GET_PRE(int k) { int ans=-2147483647; int x=rt; while (x) { if (k>t[x].data) { ans=max(ans,t[x].data); x=t[x].r; } else x=t[x].l; } return ans; } int GET_NEXT(int k) { int ans=2147483647; int x=rt; while (x) { if (k<t[x].data) { ans=min(ans,t[x].data); x=t[x].l; } else x=t[x].r; } return ans; } void DELETE(int &x,int k) { if (x==0) return; if (t[x].data==k) { if (t[x].l||t[x].r) { if (t[x].l&&(!t[x].r||t[t[x].l].key<t[t[x].r].key)) { RIGHT_ROTATE(x); DELETE(t[x].r,k); } else { LEFT_ROTATE(x); DELETE(t[x].l,k); } UPDATE(x); } else x=0; return; } if (k<t[x].data) DELETE(t[x].l,k); else DELETE(t[x].r,k); UPDATE(x); } int main() { int n,i,a,b; scanf("%d",&n); rep(i,1,n) { scanf("%d%d",&a,&b); if (a==1) INSERT(rt,b); if (a==2) DELETE(rt,b); if (a==3) printf("%d\n",GET_RANK(rt,b)+1); if (a==4) printf("%d\n",GET_DATA(rt,b)); if (a==5) printf("%d\n",GET_PRE(b)); if (a==6) printf("%d\n",GET_NEXT(b)); } }

相關推薦

NEW[平衡]模板而已

題目描述 您需要寫一種資料結構(可參考題目標題),來維護一些數,其中需要提供以下操作: 插入 x 數 刪除 x 數(若有多個相同的數,因只刪除一個) 查詢 x 數的排名(排名定義為比當前數小的數的個數 +1。若有多個相同的數,因輸出最小的排名) 查詢排

bzoj3224平衡模板(Splay)

bzoj 3224 普通平衡樹 包含此模板全部操作,可以提交至此。 #include <algorithm> #include <iostream> #include <cstring> #include <cstd

模板平衡——Treap和Splay

二叉搜尋樹($BST$):一棵帶權二叉樹,滿足左子樹的權值均小於根節點的權值,右子樹的權值均大於根節點的權值。且左右子樹也分別是二叉搜尋樹。(如下) $BST$的作用:維護一個有序數列,支援插入$x$,刪除$x$,查詢排名為$x$的數,查詢$x$的排名,求$x$的前驅後繼等操作。 時間複雜度:$O(運

BZOJ3224 Tyvj 1728 普通平衡 平衡模板

好吧,我承認,我患有帕金森:手賤啊,打錯一個字元,把if (t[k].w<x)打成了if (t[k].w>x),結果只得了20分。(淚流滿面,55555……) 這道題考察的是平衡樹的模板,只有一些平衡樹的基本操作,相信只要對平衡樹有一些瞭解的同學就能把這題A掉。

模板Trie模板

Trie樹,是一種樹形結構,是一種雜湊樹的變種。典型應用是用於統計,排序和儲存大量的字元串(但不僅限於字串),所以經常被搜尋引擎系統用於文字詞頻統計。 上面是百度百科找的,trie樹=字典樹=字首樹,下面就說說字首樹的實現。 首先trie樹的根必定是一個空節點,每一條邊代表了

平衡二叉(AVL)

平衡二叉樹的定義 (AVL—— 發明者為Adel'son-Vel'skii 和 Landis) 平衡二叉查詢樹(AVL樹),具備二叉查詢樹的特點外,還具有一個重要特點: 它的左子樹和右子樹都是平衡二叉樹,並且左子樹和右子樹的平衡因子不超過1 (也就是每個節點的平衡因子只能是1,0,-1

Python決策的python實現

uia bmp say 不知道 times otto outlook lru bgm 【Python】決策樹的python實現 2016-12-08 數據分析師Nieson 1. 決策樹是什麽? 簡單地理解,就是根據一些 feature 進行分類,每個節點提一個問

bzoj2836魔法 鏈剖分+線段

urn fin pan online char font -s class efi 題目描述 輸入 輸出 樣例輸入 4 0 1 1 2 2 3 4 Add 1 3 1 Query 0 Query 1 Query 2 樣例輸出

bzoj4785[Zjoi2017]狀數組 線段套線段

奇怪 原因 tdi function 數字 二進制位 操作 接下來 還需 題目描述 漆黑的晚上,九條可憐躺在床上輾轉反側。難以入眠的她想起了若幹年前她的一次悲慘的OI 比賽經歷。那是一道基礎的樹狀數組題。給出一個長度為 n 的數組 A,初始值都為 0,接下來進行 m 次操

BZOJ4785[Zjoi2017]狀數組 (二維線段

這也 現在 ont 平面 nbsp -s mil 比賽 turn 【BZOJ4785】[Zjoi2017]樹狀數組 Description 漆黑的晚上,九條可憐躺在床上輾轉反側。難以入眠的她想起了若幹年前她的一次悲慘的OI 比賽經歷。那是一道基礎的樹狀數組題。給出

codevs1082線段練習 3

adl for while small get color ace str 所有 題目描述 Description 給你N個數,有兩種操作: 1:給區間[a,b]的所有數增加X 2:詢問區間[a,b]的數的和。 輸入描述 Input Description 第一

BZOJ4127Abs 鏈剖分+線段

include modify 題目 etc soft upd clu set mem 【BZOJ4127】Abs Description 給定一棵樹,設計數據結構支持以下操作 1 u v d  表示將路徑 (u,v) 加d 2 u v

BZOJ3319黑白 並查集

維護 2個 bzoj3 printf highlight 集合 else cst find 【BZOJ3319】黑白樹 Description 給定一棵樹,邊的顏色為黑或白,初始時全部為白色。維護兩個操作:1.查詢u到根路徑上的第一條黑色邊的標號。2.將u到v

BZOJ3302[Shoi2005]的雙中心 DFS

ace src 表示 之間 如何 移動 sin http 我們 【BZOJ3302】[Shoi2005]樹的雙中心 Description Input 第一行為N,1<N<=50000,表示樹的節點數目,樹的節點從1到N編號。接下來N-1行

BZOJ4817[Sdoi2017]點塗色 LCT+線段

sum urn using sof 兩個 如果 std bsp char 【BZOJ4817】[Sdoi2017]樹點塗色 Description Bob有一棵n個點的有根樹,其中1號點是根節點。Bob在每個點上塗了顏色,並且每個點上的顏色不同。定義一條路徑的權值是

BZOJ4771七彩 主席+鏈的並

iter 有一個 inpu ont 實的 print algorithm 包含 char 【BZOJ4771】七彩樹 Description 給定一棵n個點的有根樹,編號依次為1到n,其中1號點是根節點。每個節點都被染上了某一種顏色,其中第i個節點的顏色為c[i]。

BZOJ4712洪水 鏈剖分優化DP+線段

表示 他還 efi 父親 管理員 out 接下來 到你 head 【BZOJ4712】洪水 Description 小A走到一個山腳下,準備給自己造一個小屋。這時候,小A的朋友(op,又叫管理員)打開了創造模式,然後飛到山頂放了格水。於是小A面前出現了一個瀑布。作為

bzoj1103POI2007大都市狀數組+差分)

sin 騎摩托車 為什麽 ons con size hint ont iostream 在經濟全球化浪潮的影響下,習慣於漫步在清晨的鄉間小路的郵遞員Blue Mary也開始騎著摩托車傳遞郵件了。不過,她經常回憶起以前在鄉間漫步的情景。昔日,鄉下有依次編號為1..n的n個小村

BZOJ4704旅行 鏈剖分+可持久化線段

-s 編號 不能 ets include 出發 oot %d rip 【BZOJ4704】旅行 Description 在Berland,有n個城堡。每個城堡恰好屬於一個領主。不同的城堡屬於不同的領主。在所有領主中有一個是國王,其他的每個領主都直接隸屬於另一位領主,

BZOJ3681Arietta 鏈剖分+可持久化線段優化建圖+網絡流

des 持久化 -s 過程 void 但是 陽光 建圖 == 【BZOJ3681】Arietta Description Arietta 的命運與她的妹妹不同,在她的妹妹已經走進學院的時候,她仍然留在山村中。但是她從未停止過和戀人 Velding 的書信往來。一天,