Section 9.1.1-3
parent
c38bf58786
commit
3aba88d3ed
@ -0,0 +1,195 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#define sz(x) (x == 0 ? 0 : x->size)
|
||||
#define update(x) \
|
||||
if (x) x->size = sz(x->child[0]) + sz(x->child[1]) + 1
|
||||
#define getVal(x) (x == 0 ? 0 : x->val)
|
||||
typedef int valType;
|
||||
const int arrSize = 100005;
|
||||
struct Node
|
||||
{
|
||||
valType val;
|
||||
int size;
|
||||
Node *child[2], *father;
|
||||
Node *Init(int x, Node *f)
|
||||
{
|
||||
val = x, size = 1, father = f, child[0] = child[1] = 0;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
typedef Node *lpNode;
|
||||
template <typename _ty, typename _typ = _ty *>
|
||||
struct allocator
|
||||
{
|
||||
private:
|
||||
int i;
|
||||
_ty *data;
|
||||
_typ *pt;
|
||||
|
||||
public:
|
||||
allocator(int size)
|
||||
{
|
||||
data = new _ty[size];
|
||||
pt = new _typ[size];
|
||||
this->i = 0;
|
||||
for (int j = 0; j < size; j++) pt[j] = &data[j];
|
||||
}
|
||||
_typ alloc()
|
||||
{
|
||||
return pt[i++];
|
||||
}
|
||||
void free(_typ ptr)
|
||||
{
|
||||
pt[--i] = ptr;
|
||||
}
|
||||
};
|
||||
struct SplayTree
|
||||
{
|
||||
private:
|
||||
lpNode root = 0;
|
||||
allocator<Node> *mem;
|
||||
void rotate(lpNode x)
|
||||
{
|
||||
if (x == 0 || x->father == 0) return;
|
||||
int d = (x == x->father->child[0]);
|
||||
lpNode y = x->father;
|
||||
y->child[d ^ 1] = x->child[d];
|
||||
if (x->child[d]) x->child[d]->father = y;
|
||||
x->father = y->father;
|
||||
if (y->father) y->father->child[y == y->father->child[1]] = x;
|
||||
y->father = x;
|
||||
x->child[d] = y;
|
||||
update(y);
|
||||
update(x);
|
||||
}
|
||||
void Splay(lpNode x, lpNode &target)
|
||||
{
|
||||
lpNode targetFather = target->father;
|
||||
while (x->father != targetFather)
|
||||
if (x->father == target)
|
||||
rotate(x);
|
||||
else if ((x->father->father->child[0] == x->father) == (x->father->child[0] == x))
|
||||
rotate(x->father), rotate(x);
|
||||
else
|
||||
rotate(x), rotate(x);
|
||||
target = x;
|
||||
}
|
||||
lpNode find(int x)
|
||||
{
|
||||
lpNode s = root;
|
||||
while (true)
|
||||
if (s == 0)
|
||||
return 0;
|
||||
else if (s->val == x)
|
||||
{
|
||||
Splay(s, root);
|
||||
return s;
|
||||
}
|
||||
else
|
||||
s = s->child[x > s->val];
|
||||
}
|
||||
lpNode join(lpNode x, lpNode y)
|
||||
{
|
||||
if (x == 0)
|
||||
return y;
|
||||
else
|
||||
{
|
||||
lpNode m = max_min(x, 1);
|
||||
Splay(m, x);
|
||||
m->child[1] = y;
|
||||
if (y) y->father = m;
|
||||
update(m);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
SplayTree(int _)
|
||||
{
|
||||
mem = new allocator<Node>(_);
|
||||
}
|
||||
lpNode max_min(lpNode x, int i)
|
||||
{
|
||||
while (x && x->child[i]) x = x->child[i];
|
||||
return x;
|
||||
}
|
||||
void insert(int x)
|
||||
{
|
||||
if (root == 0)
|
||||
root = mem->alloc()->Init(x, 0);
|
||||
else
|
||||
{
|
||||
lpNode s = root, p = 0;
|
||||
while (s)
|
||||
p = s, s = s->child[x > s->val];
|
||||
s = mem->alloc()->Init(x, p);
|
||||
p->child[x > p->val] = s;
|
||||
Splay(s, root);
|
||||
}
|
||||
}
|
||||
void remove(int x)
|
||||
{
|
||||
lpNode p = find(x);
|
||||
if (p)
|
||||
{
|
||||
root = join(p->child[0], p->child[1]);
|
||||
root->father = 0;
|
||||
mem->free(p);
|
||||
}
|
||||
}
|
||||
int rank(int x)
|
||||
{
|
||||
lpNode s = root;
|
||||
int ans = 0;
|
||||
while (s)
|
||||
if (x <= s->val)
|
||||
s = s->child[0];
|
||||
else
|
||||
ans = ans + 1 + sz(s->child[0]), s = s->child[1];
|
||||
return ans + 1;
|
||||
}
|
||||
lpNode select(int x)
|
||||
{
|
||||
lpNode s = root;
|
||||
while (s)
|
||||
if (x == sz(s->child[0]) + 1)
|
||||
return s;
|
||||
else if (x <= sz(s->child[0]))
|
||||
s = s->child[0];
|
||||
else
|
||||
x = x - 1 - sz(s->child[0]), s = s->child[1];
|
||||
}
|
||||
lpNode near(int x, int d)
|
||||
{
|
||||
lpNode s = root, ans = 0;
|
||||
while (s)
|
||||
if (d ? s->val > x : s->val < x)
|
||||
ans = s, s = s->child[d ^ 1];
|
||||
else
|
||||
s = s->child[d];
|
||||
return ans;
|
||||
}
|
||||
};
|
||||
int main()
|
||||
{
|
||||
SplayTree st(arrSize);
|
||||
int n, op, num;
|
||||
scanf("%d", &n);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
scanf("%d%d", &op, &num);
|
||||
if (op == 1)
|
||||
st.insert(num);
|
||||
else if (op == 2)
|
||||
st.remove(num);
|
||||
else if (op == 3)
|
||||
printf("%d\n", st.rank(num));
|
||||
else if (op == 4)
|
||||
printf("%d\n", getVal(st.select(num)));
|
||||
else if (op == 5)
|
||||
printf("%d\n", getVal(st.near(num, 0)));
|
||||
else if (op == 6)
|
||||
printf("%d\n", getVal(st.near(num, 1)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,150 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#define sz(x) ((x) == 0 ? 0 : (x)->sz)
|
||||
template <typename T>
|
||||
struct Allocator
|
||||
{
|
||||
int idx;
|
||||
T *data;
|
||||
T **ptr;
|
||||
Allocator(int size)
|
||||
{
|
||||
idx = 0;
|
||||
data = new T[size];
|
||||
ptr = new T *[size];
|
||||
for (int i = 0; i < size; i++) ptr[i] = &data[i];
|
||||
}
|
||||
~Allocator()
|
||||
{
|
||||
delete[] data;
|
||||
delete[] ptr;
|
||||
}
|
||||
T *alloc() { return ptr[idx++]; }
|
||||
void free(T *pt) { ptr[--idx] = pt; }
|
||||
};
|
||||
struct Treap
|
||||
{
|
||||
typedef struct Node
|
||||
{
|
||||
int val, pri, sz;
|
||||
Node *ch[2];
|
||||
void Init(int x = 0)
|
||||
{
|
||||
pri = rand();
|
||||
ch[0] = ch[1] = 0;
|
||||
val = x;
|
||||
sz = 1;
|
||||
}
|
||||
void update()
|
||||
{
|
||||
sz = 1 + sz(ch[0]) + sz(ch[1]);
|
||||
}
|
||||
} * lpNode;
|
||||
Treap(int max_size, int _seed)
|
||||
{
|
||||
srand(_seed);
|
||||
alloc = new Allocator<Node>(max_size);
|
||||
root = 0;
|
||||
}
|
||||
void ins(int x)
|
||||
{
|
||||
insert(root, x);
|
||||
}
|
||||
void del(int x)
|
||||
{
|
||||
remove(root, x);
|
||||
}
|
||||
int rnk(int x)
|
||||
{
|
||||
int ans = 1;
|
||||
lpNode cur = root;
|
||||
while (cur)
|
||||
if (x <= cur->val)
|
||||
cur = cur->ch[0];
|
||||
else
|
||||
ans += sz(cur->ch[0]) + 1, cur = cur->ch[1];
|
||||
return ans;
|
||||
}
|
||||
int kth(int x)
|
||||
{
|
||||
lpNode cur = root;
|
||||
while (cur)
|
||||
if (x == sz(cur->ch[0]) + 1)
|
||||
return cur->val;
|
||||
else if (x <= sz(cur->ch[0]))
|
||||
cur = cur->ch[0];
|
||||
else
|
||||
x -= sz(cur->ch[0]) + 1,
|
||||
cur = cur->ch[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
Allocator<Node> *alloc;
|
||||
lpNode root;
|
||||
void rotate(lpNode &node, int d)
|
||||
{
|
||||
if (node == 0) return;
|
||||
lpNode ch = node->ch[d ^ 1];
|
||||
if (ch)
|
||||
{
|
||||
node->ch[d ^ 1] = ch->ch[d];
|
||||
ch->ch[d] = node;
|
||||
node = ch;
|
||||
node->ch[d]->update();
|
||||
node->update();
|
||||
}
|
||||
}
|
||||
void insert(lpNode &node, int x)
|
||||
{
|
||||
if (node == 0)
|
||||
(node = alloc->alloc())->Init(x);
|
||||
else
|
||||
{
|
||||
int cmp = x < node->val;
|
||||
insert(node->ch[cmp ^ 1], x);
|
||||
node->update();
|
||||
if (node->ch[cmp ^ 1]->pri < node->pri) rotate(node, cmp);
|
||||
}
|
||||
}
|
||||
void remove(lpNode &node, int x)
|
||||
{
|
||||
if (node == 0)
|
||||
return;
|
||||
else
|
||||
{
|
||||
if (x < node->val)
|
||||
remove(node->ch[0], x);
|
||||
else if (x > node->val)
|
||||
remove(node->ch[1], x);
|
||||
else if (node->ch[0] == 0)
|
||||
node = node->ch[1];
|
||||
else if (node->ch[1] == 0)
|
||||
node = node->ch[0];
|
||||
else
|
||||
{
|
||||
int d = node->ch[0]->pri < node->ch[1]->pri;
|
||||
rotate(node, d);
|
||||
remove(node->ch[d], x);
|
||||
}
|
||||
if (node) node->update();
|
||||
}
|
||||
}
|
||||
};
|
||||
int main()
|
||||
{
|
||||
Treap T(100005, 3224);
|
||||
int n;
|
||||
scanf("%d", &n);
|
||||
for (int i = 0, op, x; i < n; i++)
|
||||
{
|
||||
scanf("%d%d", &op, &x);
|
||||
if (op == 1) T.ins(x);
|
||||
if (op == 2) T.del(x);
|
||||
if (op == 3) printf("%d\n", T.rnk(x));
|
||||
if (op == 4) printf("%d\n", T.kth(x));
|
||||
if (op == 5) printf("%d\n", T.kth(T.rnk(x) - 1));
|
||||
if (op == 6) printf("%d\n", T.kth(T.rnk(x + 1)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Loading…
Reference in new issue