【BZOJ - 3224】普通平衡树(Splay模板题)
生活随笔
收集整理的這篇文章主要介紹了
【BZOJ - 3224】普通平衡树(Splay模板题)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題干:
您需要寫一種數據結構(可參考題目標題),來維護一些數,其中需要提供以下操作:
1. 插入x數
2. 刪除x數(若有多個相同的數,因只刪除一個)
3. 查詢x數的排名(若有多個相同的數,因輸出最小的排名)
4. 查詢排名為x的數
5. 求x的前驅(前驅定義為小于x,且最大的數)
6. 求x的后繼(后繼定義為大于x,且最小的數)
Input
第一行為n,表示操作的個數,下面n行每行有兩個數opt和x,opt表示操作的序號(1<=opt<=6)
Output
對于操作3,4,5,6每行輸出一個數,表示對應答案
Sample Input
10 1 106465 4 1 1 317721 1 460929 1 644985 1 84185 1 89851 6 81968 1 492737 5 493598
Sample Output
106465 84185 492737
Hint
1.n的數據范圍:n<=100000
2.每個數的數據范圍:[-2e9,2e9]
解題報告:
Splay的大模板題。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX =100007;//= 2e5 + 5; int fa[MAX],cnt[MAX],tr[MAX][2],size[MAX],val[MAX],tot,root; inline bool get(int x) {return tr[fa[x]][1]==x; } inline void clear(int x) {fa[x]=cnt[x]=tr[x][0]=tr[x][1]=size[x]=val[x]=0; } inline void pushup(int x) {//更新x節點的信息 if(x == 0) return;//其實不加也行,因為不會去維護根節點的父節點的關系。size[x] = cnt[x]; // if(tr[x][0]) size[x] += size[tr[x][0]] ; // if(tr[x][1]) size[x] += size[tr[x][1]] ;沒啥用、、size[x] += size[tr[x][0]] + size[tr[x][1]]; } inline void rotate(int x) {//以下注釋默認我是我爸的左兒子 int old = fa[x],oldf = fa[old],w=get(x),ww=get(old);//修改我爸和我右兒子的關系 tr[old][w] = tr[x][w^1]; fa[tr[old][w]]=old;//修改我和我爸的關系 tr[x][w^1] = old;fa[old] = x;//修改我和我爺爺的關系 fa[x] = oldf;if(oldf) tr[oldf][ww] = x;pushup(old);pushup(x); } inline void splay(int x) {for(int old=fa[x]; old = fa[x]; rotate(x)) {//默認根節點是0的情況下才可以這么用判斷條件 if(fa[old]) {rotate(get(x) == get(old) ? old : x);}}root = x; } inline void insert(int x) {//x為權值 if(root == 0) {val[++tot] = x;root=tot;cnt[tot]=size[tot]=1;fa[tot] = tr[tot][0]=tr[tot][1]=0;return; }int cur = root,old = 0;while(1) {if(x == val[cur]) {cnt[cur]++;pushup(cur);pushup(old);splay(cur);return;}old = cur;cur = tr[cur][val[cur] < x];if(cur == 0) {val[++tot] = x;fa[tot] = old; tr[tot][0]=tr[tot][1]=0; tr[old][x>val[old]] = tot;//維護父節點和孩子節點 cnt[tot] = size[tot] = 1;pushup(old); splay(tot);return;}} } inline int pre(int x) {int cur = root,old=0;while(cur) {if(val[cur] < x) old = cur,cur = tr[cur][1];else cur = tr[cur][0]; }return old; } inline int nxt(int x) {int cur = root,old = 0;while(cur) {if(val[cur] > x) old = cur,cur = tr[cur][0];else cur = tr[cur][1];}return old; } //inline int pre() { // int cur = tr[root][0]; // while(tr[cur][1]) cur = tr[cur][1]; // return cur; //} //inline int nxt() { // int cur = tr[root][1]; // while(tr[cur][0]) cur = tr[cur][0]; // return cur; //}inline int Rank(int x) {//查詢x的Rank int cur = root,res = 0;while(1) { // if(cur == 0) return -1;//說明數據非法 if(x < val[cur]) cur = tr[cur][0];else {res += size[tr[cur][0]];if(x == val[cur]) {splay(cur); return res+1;}//此時x和樹中的點重合,樹中不允許有兩個相同的點res += cnt[cur]; cur = tr[cur][1];}} } inline int kth(int x) {//查詢排名為x的數的val int cur = root;while(1) {if(tr[cur][0] && x <= size[tr[cur][0]]) cur = tr[cur][0];else {int tmp = size[tr[cur][0]] + cnt[cur];if(x <= tmp) {splay(cur);return val[cur];}x -= tmp;cur = tr[cur][1];}} } inline void del(int x) {Rank(x);//找到x的排名并把它旋轉上來if(cnt[root] > 1) {cnt[root]--;return;}if(!tr[root][0] && !tr[root][1]) root=0;//可加個clear();函數else if(!tr[root][0]) {root = tr[root][1];fa[root]=0;} //pushup(root);else if(!tr[root][1]) {root = tr[root][0];fa[root]=0;}//pushup(root);else {int leftbig = tr[root][0],oldrt=root;while(tr[leftbig][1]) leftbig = tr[leftbig][1];splay(leftbig);tr[root][1]=tr[oldrt][1];fa[tr[oldrt][1]]=root;pushup(root);} } //全程表示根節點不是0,但是根節點的父節點,我們認為是0 (fa[rt]==0) int main() {int n;cin>>n;for(int i = 1; i<=n; i++) {int op,x;scanf("%d%d",&op,&x);if(op == 1) insert(x);if(op == 2) del(x);if(op == 3) printf("%d\n",Rank(x));if(op == 4) printf("%d\n",kth(x));if(op == 5) printf("%d\n",val[pre(x)]);if(op == 6) printf("%d\n",val[nxt(x)]);}return 0 ; }總結:嗚嗚嗚好難寫、、、
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【BZOJ - 3224】普通平衡树(Splay模板题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 5G商用三周年 物联网好戏才刚刚开始
- 下一篇: 男子下楼太快冲出6楼窗外悬在半空中 网友