RT,wa#3,TLE#4~#11,看起来像是删除操作以及根的判定有误,求大佬查错
#include<bits/stdc++.h>
namespace RBT
{
struct tree
{
int val, color, fa, ch[2], size;
}f[2000005];
#define fa(x) (f[x].fa)
#define ls(x) (f[x].ch[0])
#define rs(x) (f[x].ch[1])
#define size(x) (f[x].size)
#define color(x) (f[x].color)
int root, cnt;
bool identify(int p)
{
return rs(fa(p)) == p;
}
void update(int p)
{
size(p) = size(ls(p)) + size(rs(p)) + 1;
}
void rotate_update(int p)
{
color(ls(p)) = color(rs(p)) = 1;
color(p) = 0;
}
void connect(int son, int fa, int k)
{
fa(son) = fa;
f[fa].ch[k] = son;
}
void rotate(int x)
{
int y = fa(x), z = fa(y), yk = identify(x), zk = identify(y), b = f[x].ch[yk ^ 1];
connect(b, y, yk);
connect(y, x, yk ^ 1);
connect(x, z, zk);
update(y);
update(x);
if (fa(x) == 0)
{
root = x;
if (color(root))
{
color(root) = 0;
}
}
else if (fa(y) == 0 && y)
{
root = y;
if (color(root))
{
color(root) = 0;
}
}
else if (fa(z) == 0 && z)
{
root = z;
if (color(root))
{
color(root) = 0;
}
}
else if (fa(b) == 0 && b)
{
root = b;
if (color(root))
{
color(root) = 0;
}
}
//if(color(x)==1&&(color(ls(x))||color(rs(x))))
}
void slovedoublered(int x);
void sloveadd(int x)
{
int y = fa(x), z = fa(y), yk = identify(x), zk = identify(y);
int w = f[z].ch[zk ^ 1];
if (w == 0);
else if (color(w) == 1)
{
slovedoublered(x);
}
else if (color(w) == 0)
{
if (yk != zk)
{
rotate(x);
rotate(x);
rotate_update(x);
}
else
{
rotate(y);
rotate_update(y);
}
}
if (fa(x) == 0)
{
root = x;
if (color(root))
{
color(root) = 0;
}
}
if (fa(y) == 0 && y)
{
root = y;
if (color(root))
{
color(root) = 0;
}
}
}
void slovedoublered(int x)
{
int y = fa(x), z = fa(y), chk = identify(y);
int w = f[z].ch[chk ^ 1];
color(w) = color(y) = 0;
color(z) = 1;
sloveadd(z);
}
void insert(int x)
{
int p = root;
if (root == 0)
{
root = ++cnt;
f[cnt].size = 1;
f[cnt].val = x;
++cnt;
f[cnt].val = -1;
connect(cnt, root, 0);
++cnt;
f[cnt].val = -1;
connect(cnt, root, 1);
return;
}
while (f[p].val != -1)
{
if (f[p].val >= x)
{
p = f[p].ch[0];
}
else
{
p = f[p].ch[1];
}
}
f[p].color = 1;
f[p].val = x;
f[p].size = 1;
cnt++;
f[cnt].val = -1;
connect(cnt, p, 0);
cnt++;
f[cnt].val = -1;
connect(cnt, p, 1);
sloveadd(p);
while (p != 0)
{
update(p);
p = fa(p);
}
}
int kth(int k)
{
int p = root;
while (1)
{
if (f[ls(p)].size + 1 < k)
{
k -= size(ls(p)) + 1;
p = rs(p);
}
else if (size(ls(p)) >= k)
{
p = ls(k);
}
else
{
return f[p].val;
}
}
}
int rank(int k)
{
int res = 0, p = root;
while (1)
{
if (k < f[p].val)
{
p = ls(p);
}
else if (k > f[p].val)
{
res += size(ls(p)) + 1;
p = rs(p);
}
else
{
return res + size(ls(p)) + 1;
}
}
}
void slovedel(int x)
{
if (x == root)return;
int y = fa(x), z = fa(y), yk = identify(x), zk = identify(y);
int b = f[y].ch[yk ^ 1];
if (color(b) == 0)
{
if (color(ls(b)) == color(rs(b)) && color(ls(b)) == 0)
{
if (color(y) == 1)
{
std::swap(color(b), color(y));
}
else
{
color(b) = 1;
slovedel(y);
}
}
else
{
int bk = identify(b);
if (bk == 0)
{
if (color(ls(b)) == 0)
{
rotate(b);
std::swap(color(b), color(rs(b)));
slovedel(x);
}
else
{
//rotate(y);
rotate(b);
std::swap(color(y), color(b));
color(ls(b)) = 0;
}
}
else
{
if (color(rs(b)) == 0)
{
rotate(b);
std::swap(color(b), color(ls(b)));
slovedel(x);
}
else
{
//rotate(y);
rotate(b);
std::swap(color(y), color(b));
color(rs(b)) = 0;
}
}
}
}
else
{
rotate(b);
std::swap(color(y), color(b));
slovedel(x);
}
if (fa(x) == 0)
{
root = x;
if (color(root))
{
color(root) = 0;
}
}
if (fa(y) == 0 && y)
{
root = y;
if (color(root))
{
color(root) = 0;
}
}
}
void del(int x)
{
int p = root;
if (root == 0)return;
while (f[p].val != x)
{
if (x <= f[p].val)
{
p = ls(p);
}
else
{
p = rs(p);
}
}
if (f[ls(p)].val == -1 && f[rs(p)].val == -1)
{
int yk = identify(p);
connect(ls(p), fa(p), yk);
if (color(p) == 0)
{
slovedel(ls(p));
}
while (p)
{
update(p);
p = fa(p);
}
}
else if ((f[ls(p)].val == -1 && f[rs(p)].val != -1) || (f[ls(p)].val != -1 && f[rs(p)].val == -1))
{
if (f[rs(p)].val == -1)
{
int k = identify(p);
connect(ls(p), fa(p), k);
color(ls(p)) = 0;
}
else
{
int k = identify(p);
connect(rs(p), fa(p), k);
color(ls(p)) = 0;
}
while (p)
{
update(p);
p = fa(p);
}
}
else if (f[ls(p)].val != -1 && f[rs(p)].val != -1)
{
int q = ls(p);
while (f[rs(q)].val != -1)
{
q = rs(q);
}
std::swap(f[p].val, f[q].val);
f[q].val = -1;
f[q].size = 0;
slovedel(p);
while (q)
{
update(q);
q = fa(q);
}
}
}
int pre(int k)
{
int p = root, pre = 0;
while (f[p].val != -1)
{
if (f[p].val < k)
{
pre = f[p].val;
p = rs(p);
}
else p = ls(p);
}
return pre;
}
int nxt(int k)
{
int p = root, nxt = 0;
while (f[p].val != -1)
{
if (f[p].val > k)
{
nxt = f[p].val, p = ls(p);
}
else
{
p = rs(p);
}
}
return nxt;
}
}
namespace CCCP
{
using namespace RBT;
int n, m, flag;
using std::cin;
void work()
{
cin >> n;
for (int i = 1;i <= n;i++)
{
int opt, x;
cin >> opt >> x;
switch (opt)
{
case 1:
insert(x);
break;
case 2:
del(x);
break;
case 3:
std::cout << rank(x) << '\n';
break;
case 4:
std::cout << kth(x) << '\n';
break;
case 5:
std::cout << pre(x) << '\n';
break;
case 6:
std::cout << nxt(x) << '\n';
}
}
}
}
int main()
{
return CCCP::work(), 0;
}