题目链接
此题要求实现6种操作
- 插入x
- 删除x
- 查询x数的排名
- 查询排名为x的数
- 求x的前驱
- 求x的后继
既然题目已经明确指出了可以使用treap,那就写一个指针版不维护父节点的treap。
#include<bits/stdc++.h>
#define N 100001
using namespace std;
struct Treap
{
int value, rank, size, re;
Treap * l, * r;
}p[N], * root = NULL;
int len = 0;
int n, ans;
inline int read()
{
int f = 0, fu = 1;
char c = getchar();
while(c < '0' || c > '9')
{
if(c == '-') fu = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
{
f = (f << 3) + (f << 1) + c - 48;
c = getchar();
}
return f * fu;
}
inline void update(Treap * u)
{
u -> size = u -> re;
if(u -> l != NULL) u -> size += u -> l -> size;
if(u -> r != NULL) u -> size += u -> r -> size;
}
inline void tl(Treap *& u)
{
Treap * tmp = u -> r;
u -> r = tmp -> l;
tmp -> l = u;
tmp -> size = u -> size;
update(u);
u = tmp;
}
inline void tr(Treap *& u)
{
Treap * tmp = u -> l;
u -> l = tmp -> r;
tmp -> r = u;
tmp -> size = u -> size;
update(u);
u = tmp;
}
inline void in_Treap(Treap *& u, int x)
{
if(u == NULL)
{
u = &p[++len];
u -> value = x;
u -> rank = rand();
u -> size = 1;
u -> re = 1;
u -> l = NULL;
u -> r = NULL;
return;
}
u -> size++;
if(u -> value == x)
{
u -> re++;
return;
}
if(u -> value > x)
{
in_Treap(u -> l, x);
if(u -> l -> rank < u -> rank) tr(u);
}
else
{
in_Treap(u -> r, x);
if(u -> r -> rank < u -> rank) tl(u);
}
}
inline void delete_Treap(Treap *& u, int x)
{
if(u == NULL) return;
if(u -> value == x)
{
if(u -> re >= 2)
{
u -> re--;
u -> size--;
return;
}
if(u -> l == NULL) u = u -> r;
else if(u -> r == NULL) u = u -> l;
else
{
if(u -> l -> rank < u -> r -> rank)
{
tr(u);
delete_Treap(u, x);
}
else
{
tl(u);
delete_Treap(u, x);
}
}
}
else
{
if(x < u -> value)
{
u -> size--;
delete_Treap(u -> l, x);
}
else
{
u -> size--;
delete_Treap(u -> r, x);
}
}
}
inline int find1(Treap * u, int x)
{
if(u == NULL) return 0;
if(u -> value == x)
{
if(u -> l != NULL) return u -> l -> size + 1;
return 1;
}
if(u -> value > x) return find1(u -> l, x);
if(u -> value < x)
{
if(u -> l != NULL) return u -> l -> size + u -> re + find1(u -> r, x);
return find1(u -> r, x) + u -> re;
}
}
inline int find2(Treap * u, int x)
{
if(u == NULL) return 0;
if(u -> l == NULL)
{
if(x > u -> re) return find2(u -> r, x - u -> re);
return u -> value;
}
if(x <= u -> l -> size) return find2(u -> l, x);
if(x > u -> l -> size + u -> re) return find2(u -> r, x - u -> l -> size - u -> re);
return u -> value;
}
inline void find3(Treap * u, int x)
{
if(u == NULL) return;
if(u -> value < x)
{
ans = u -> value;
find3(u -> r, x);
}
else find3(u -> l, x);
}
inline void find4(Treap * u, int x)
{
if(u == NULL) return;
if(u -> value > x)
{
ans = u -> value;
find4(u -> l, x);
}
else find4(u -> r, x);
}
int main()
{
srand(998244353);
n = read();
for(int i = 1; i <= n; i++)
{
int a = read(), b = read();
if(a == 1) in_Treap(root, b);
if(a == 2) delete_Treap(root, b);
if(a == 3) printf("%d\n", find1(root, b));
if(a == 4) printf("%d\n", find2(root, b));
if(a == 5)
{
find3(root, b);
printf("%d\n", ans);
}
if(a == 6)
{
find4(root, b);
printf("%d\n", ans);
}
}
return 0;
}
跑的也不算慢,没开O2是168ms。
fhq treap不会写,不知道什么时候才能填上这个坑