网上都说 FHQ-Treap 码量小,功能也强,蒟蒻就去学了学。
然后 愉 快 地写了 179 行。。。
#include <bits/stdc++.h>
using namespace std;
int n;
int opt, x;
namespace FHQ_Treap_Space
{
const int MAXN = 1e5 + 5;
const int IMPOSSIBLE = 1e9;
struct FHQ_Treap{
int root, sum;
int u, v, w, p;
int result;
struct Node{
int value;
int size;
int priority;
int left;
int right;
};
Node tree[MAXN];
void Initialize()
{
//初始化
srand(time(0));
root = sum = 0;
tree[0].value = IMPOSSIBLE;
tree[0].size = 0;
tree[0].priority = 0;
tree[0].left = 0;
tree[0].right = 0;
return;
}
int Make_Node(int value)
{
//新建节点,值为 value,返回新建的节点
sum++;
tree[sum].value = value;
tree[sum].size = 1;
tree[sum].priority = rand();
tree[sum].left = 0;
tree[sum].right = 0;
return sum;
}
void Push_Up(int u)
{
//计算子树 u 的大小
tree[u].size = tree[tree[u].left].size + tree[tree[u].right].size + 1;
return;
}
void Split(int value, int w, int &u, int &v)
{
//分裂子树 w,值 <= value 的被分到子树 u,值 > value 的被分到子树 v
if(w == 0){
u = v = 0;
return;
}
if(tree[w].value <= value){
u = w;
Split(value, tree[w].right, tree[w].right, v);
}
if(tree[w].value > value){
v = w;
Split(value, tree[w].left, u, tree[w].left);
}
Push_Up(w);
return;
}
int Merge(int u, int v)
{
//合并子树 u,v,返回合并后的根节点
if(u == 0 || v == 0) return u + v;
if(tree[u].priority <= tree[v].priority){
tree[u].right = Merge(tree[u].right, v);
Push_Up(u);
return u;
}
if(tree[u].priority > tree[v].priority){
tree[v].left = Merge(u, tree[v].left);
Push_Up(v);
return v;
}
}
void Insert(int value)
{
//插入值为 value 的节点
Split(value, root, u, v);
root = Merge(Merge(u, Make_Node(value)), v);
return;
}
void Delete(int value)
{
//删除值为 value 的节点
Split(value, root, u, w);
Split(value-1, u, u, v);
v = Merge(tree[v].left, tree[v].right);
root = Merge(Merge(u, v), w);
return;
}
int Size()
{
//查询节点个数
return tree[root].size;
}
bool Search(int value)
{
//查询值为 value 的节点是否存在
if(Size() == 0) return false;
Split(value, root, u, w);
Split(value-1, u, u, v);
if(tree[v].value == value) result = 1;
else result = 0;
root = Merge(Merge(u, v), w);
return result;
}
int Get_Rank(int value)
{
//查询值为 value 的节点的排名
if(Search(value) == false) return IMPOSSIBLE;
Split(value-1, root, u, v);
result = tree[u].size + 1;
root = Merge(u, v);
return result;
}
int Get_Value(int rank)
{
//查询排名为 rank 的节点的值
if(rank <= 0 || rank > Size()) return IMPOSSIBLE;
p = root;
while(true){
if(tree[tree[p].left].size + 1 == rank) break;
if(tree[tree[p].left].size + 1 <= rank){
rank = rank - tree[tree[p].left].size - 1;
p = tree[p].right;
}
if(tree[tree[p].left].size + 1 > rank) p = tree[p].left;
}
return tree[p].value;
}
int Get_Prefix(int value)
{
//查询值 < value 的节点中,值最大的节点的值
if(Size() == 0) return IMPOSSIBLE;
Split(value-1, root, u, v);
p = u;
while(tree[p].right != 0) p = tree[p].right;
result = tree[p].value;
root = Merge(u, v);
return result;
}
int Get_Suffix(int value)
{
//查询值 > value 的节点中,值最小的节点的值
if(Size() == 0) return IMPOSSIBLE;
Split(value, root, u, v);
p = v;
while(tree[p].left != 0) p = tree[p].left;
result = tree[p].value;
root = Merge(u, v);
return result;
}
};
}
FHQ_Treap_Space :: FHQ_Treap t;
int main()
{
t.Initialize();
scanf("%d", &n);
while(n--){
scanf("%d%d", &opt, &x);
if(opt == 1) t.Insert(x);
if(opt == 2) t.Delete(x);
if(opt == 3) printf("%d\n", t.Get_Rank(x));
if(opt == 4) printf("%d\n", t.Get_Value(x));
if(opt == 5) printf("%d\n", t.Get_Prefix(x));
if(opt == 6) printf("%d\n", t.Get_Suffix(x));
}
return 0;
}
//FHQ-Treap