題目描述您需要寫一種資料結構(可參考題目標題),來維護一些數,其中需要提供以下操作:
插入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,且最小的數 總算...