您的位置:首页 > 其它

Splay初步【bzoj1503】

2015-12-04 12:40 309 查看
做了一道水题,把bzoj1503用Splay重新写了一下。

#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define REP(i, a, b) for (int i = a; i < b; i++)
#define drep(i, a, b) for (int i = a; i >= b; i--)
#define mp make_pair
#define pb push_back
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second
using namespace std;
typedef long long i64;
typedef pair<int, int> pii;
const int inf = ~0U >> 1;
const i64 INF = ~0ULL >> 1;
//***************************

struct node {
node *pre, *s[2];
int key, size, mul;
node() { pre = s[0] = s[1] = 0; size = mul = 1; }
node(int _key) :key(_key) { pre = s[0] = s[1] = 0; size = mul = 1; }
bool getlr() { return pre->s[1] == this; }
node *link(int w, node *p) { s[w] = p; if (p) p->pre = this; return this; }
void update() { size = mul + (s[0] ? s[0]->size : 0) + (s[1] ? s[1]->size : 0); }
} *root;
void rot(node* p) {
node *q = p->pre->pre;
p->getlr() ? p->link(0, p->pre->link(1, p->s[0])) : p->link(1, p->pre->link(0, p->s[1]));
p->pre->update();
if (q) q->link(q->s[1] == p->pre, p);
else { p->pre = 0; root = p; }
}
void splay(node *p, node *tar) {
while (p->pre != tar && p->pre->pre != tar)
p->getlr() == p->pre->getlr() ? (rot(p->pre), rot(p)) : (rot(p), rot(p));
if (p->pre) rot(p);
p->update();
}
void insrt(int k) {
node *p = root, *q = NULL;
while (p) {
q = p;
if (k > p->key) p = p->s[1];
else if (k < p->key) p = p->s[0];
else break;
}
if (!p) {p = new node(k);
if (!q) { root = p; return; }
q->link(q->key < k, p); q->update(); splay(p, 0);
}
else { p->mul++; splay(p, 0); }
}
node *findkth(int x) {
node *p = root;
node *t;
while (1) {
int w = (p->s[0] ? p->s[0]->size : 0);
if (x <= w) t = p->s[0];
else if (x > w + p->mul) { x -= w + p->mul; t = p->s[1]; }
else break;
p = t;
}
splay(p, 0); return p;
}

node *find(node *p, int x) {
if (p->key < x) return find(p->s[1], x);
else if (p->key > x) return find(p->s[0], x);
else return p;
}

int main() {
int ori(0);
int n, m;
scanf("%d%d", &n, &m);
int tot(0);
char op[5]; int x;
while (n--) {
scanf("%s%d", op, &x);
if (op[0] == 'I') {
if (x >= m) {
ori++;
insrt(x - tot);
}
}
else if (op[0] == 'A') tot += x;
else if (op[0] == 'S') {
tot -= x;
insrt(m - tot - 1);
splay(find(root, m - tot - 1), 0);
root = root->s[1];
if (root) root->pre = 0;
}
else if (op[0] == 'F') {
if (!root || x > root->size) puts("-1");
else printf("%d\n", findkth(root->size - x + 1)->key + tot);
}
}
printf("%d\n", ori - (root ? root->size : 0));
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: