【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(運
【BZOJ】3224 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 第一
【BZOJ4127】Abs 樹鏈剖分+線段樹
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面前出現了一個瀑布。作為
【bzoj1103】【POI2007】【大都市】(樹狀數組+差分)
sin 騎摩托車 為什麽 ons con size hint ont iostream 在經濟全球化浪潮的影響下,習慣於漫步在清晨的鄉間小路的郵遞員Blue Mary也開始騎著摩托車傳遞郵件了。不過,她經常回憶起以前在鄉間漫步的情景。昔日,鄉下有依次編號為1..n的n個小村
【BZOJ4704】旅行 樹鏈剖分+可持久化線段樹
-s 編號 不能 ets include 出發 oot %d rip 【BZOJ4704】旅行 Description 在Berland,有n個城堡。每個城堡恰好屬於一個領主。不同的城堡屬於不同的領主。在所有領主中有一個是國王,其他的每個領主都直接隸屬於另一位領主,
【BZOJ3681】Arietta 樹鏈剖分+可持久化線段樹優化建圖+網絡流
des 持久化 -s 過程 void 但是 陽光 建圖 == 【BZOJ3681】Arietta Description Arietta 的命運與她的妹妹不同,在她的妹妹已經走進學院的時候,她仍然留在山村中。但是她從未停止過和戀人 Velding 的書信往來。一天,