洛谷 3369 模板 普通平衡樹

2021-09-24 22:27:11 字數 3216 閱讀 3873

題目描述

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

插入x數

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

查詢x數的排名(排名定義為比當前數小的數的個數+1。若有多個相同的數,因輸出最小的排名)

查詢排名為x的數

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

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

輸入輸出格式

輸入格式:

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

輸出格式:

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

輸入輸出樣例

輸入樣例#1:

101 106465

4 11 317721

1 460929

1 644985

1 84185

1 89851

6 81968

1 492737

5 493598

//treap

#include#include#include#include#include#includetypedef long long ll;

using namespace std;

int rd()

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

return flag * out;

}//第一次打treap,不壓行寫注釋xd

const int maxn = 1000019,inf = 1e9;

//平衡樹,利用bst性質查詢和修改,利用隨機和堆優先順序來保持平衡,把樹的深度控制在log n,保證了操作效率

//基本平衡樹有以下幾個比較重要的函式:新建,插入,刪除,旋轉

//節點的基本屬性有val(值),dat(隨機出來的優先順序)

//通過增加屬性,結合bst的性質可以達到一些效果,如size(子樹大小,查詢排名),cnt(每個節點包含的副本數)等

int na;

int ch[maxn][2];//[i][0]代表i左兒子,[i][1]代表i右兒子

int val[maxn],dat[maxn];

int size[maxn],cnt[maxn];

int tot,root;

int new(int v)

void pushup(int id)

void build()

void rotate(int &id,int d)//旋轉實質是(通過交換本節點和其某個葉子節點)把鏈叉開成二叉形狀(從而控制深度),可以看圖理解一下

void insert(int &id,int v)

if(v == val[id])cnt[id]++;//若節點已存在,則副本數++;

else

pushup(id);//現在更新一下本節點的資訊

}void remove(int &id,int v)//若副本不止乙個,減去乙個就好

if(ch[id][0] || ch[id][1])

else rotate(id,0),remove(ch[id][0],v);

pushup(id);

}else id = 0;//發現本節點是葉子節點,直接刪除

return ;//這個return對應的是檢索到值de所有情況

}v < val[id] ? remove(ch[id][0],v) : remove(ch[id][1],v);//繼續bst性質

pushup(id);

}int get_rank(int id,int v)

int get_val(int id,int rank)

int get_pre(int v)

return pre;

}int get_next(int v)

return next;

}int main()

return 0;

}

//splay

#includeusing namespace std;

const int maxl=200005;

const int inf=2147480000;

class splay;

node e[maxl];//splay樹主體

int n,points;//使用儲存數,元素數

inline void update(int x)

int identify(int x)

inline void connect(int x,int f,int son)//作用:使得x的father=f,f的son=x.

inline void rotate(int x)

inline void splay(int at,int to)

else}}

inline int crepoint(int v,int father)

inline void destroy(int x)

public:

inline int getroot()

inline int find(int v)

int next=v1)

if(!e[deal].ch[0])

else

destroy(deal);

}inline int rank(int v)

return result;

}#undef root

};template inline bool scan_d(t &ret)

while (c != '-' && (c < '0' || c > '9'))

sgn = (c == '-') ? -1 : 1;

ret = (c == '-') ? 0 : (c - '0');

while (c = getchar(), c >= '0' && c <= '9')

ret *= sgn;

return 1;

}template void out(t a)

if (a >= 10)

putchar(a % 10 + '0');

} splay f;

int n=0,opt=0,x;

int main()

return 0;

}

洛谷P3369 模板 普通平衡樹

本蒟蒻最近剛剛學會平衡樹,特來寫篇部落格以加深印象。我的意思是若寫的不好望各位奆佬多多包含!插入 x 數 刪除 x 數 若有多個相同的數,因只刪除乙個 查詢 x 數的排名 排名定義為比當前數小的數的個數 1 若有多個相同的數,因輸出最小的排名 查詢排名為 x 的數 求 x 的前驅 前驅定義為小於 x...

洛谷P3369 模板 普通平衡樹

插入x數 刪除x數 若有多個相同的數,因只刪除乙個 查詢x數的排名 排名定義為比當前數小的數的個數 1。若有多個相同的數,因輸出最小的排名 查詢排名為x的數 求x的前驅 前驅定義為小於x,且最大的數 求x的後繼 後繼定義為大於x,且最小的數 輸入格式 第一行為n,表示操作的個數,下面n行每行有兩個數...

洛谷P3369 模板 普通平衡樹 Treap

插入xxx數 刪除x xx數 若有多個相同的數,因只刪除乙個 查詢x xx數的排名 排名定義為比當前數小的數的個數 1 1 1。若有多個相同的數,因輸出最小的排名 查詢排名為x xx的數 求x xx的前驅 前驅定義為小於x xx,且最大的數 求x xx的後繼 後繼定義為大於x xx,且最小的數 總算...