题意:在stack的操作上加一个输出当前栈中的中位数的操作。
思路:找中位数可以用splay,其它按照栈操作就好,当然也可以用二分+bit找中位数毕竟数字不大。
代码
splay
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <climits>
using namespace std;
template <class T, size_t size>
struct MemoryPool {
T buf[size], *tail, *end;
inline T *alloc() {
if (top) return st[--top];
if (tail != end) return tail++;
return new T;
}
MemoryPool() : tail(buf), end(buf + size), top(0) {}
int top;
T *st[size];
inline void recycle(T *x) {
if (top > size) delete x;
else st[top++] = x;
}
};
const int MAXN = 200000;
template <class T, T INF>
struct Splay {
enum Relation { L = 0, R = 1 };
struct Node {
Node *child[2], *parent, **root;
T value;
int size, count;
inline void init(Node *parent, const T &value, Node **root) {
this->parent = parent;
this->value = value;
this->root = root;
this->count = this->size = 1;
child[0] = child[1] = NULL;
}
inline Relation relation() {
return this == parent->child[L] ? L : R;
}
inline void recycle(MemoryPool<Node, MAXN> &pool) {
if (child[L]) pool.recycle(child[L]);
if (child[R]) pool.recycle(child[R]);
}
inline void maintain() {
size = count + (child[L] ? child[L]->size : 0) + (child[R] ? child[R]->size : 0);
}
inline void rotate() {
Relation x = relation();
Node *oldParent = parent;
if (oldParent->parent) oldParent->parent->child[oldParent->relation()] = this;
parent = oldParent->parent; oldParent->child[x] = child[x^1];
if (child[x^1]) child[x^1]->parent = oldParent;
child[x^1] = oldParent; oldParent->parent = this; oldParent->maintain(); maintain();
if (!parent) *root = this;
}
inline void splay(Node *targetParent = NULL) {
while (parent != targetParent) {
if (parent->parent == targetParent) {
rotate();
} else {
if (parent->relation() == relation()) parent->rotate(), rotate();
else rotate(), rotate();
}
}
}
inline Node *precursor() {
splay();
Node *v = child[L];
while (v->child[R]) v = v->child[R];
return v;
}
inline Node *successor() {
splay();
Node *v = child[R];
while (v->child[L]) v = v->child[L];
return v;
}
inline int rank() {return child[L] ? child[L]->size : 0;}
} *root;
MemoryPool<Node, MAXN> pool;
Splay() : root(NULL) {insert(INF), insert(-INF);}
inline Node *find(const T &value) {
Node *v = root;
while (v && value != v->value) {
v = (value < v->value ? v->child[L] : v->child[R]);
}
return v ? (v->splay(), v) : NULL;
}
inline Node *insert(const T &value) {
Node *v = find(value);
if (v) {
v->count++;
v->maintain();
return v;
}
Node **target = &root, *parent = NULL;
while (*target) {
parent = *target;
parent->size++;
target = (value < parent->value ? &parent->child[L] : &parent->child[R]);
}
*target = pool.alloc(); (*target)->init(parent, value, &root); (*target)->splay();
return root;
}
inline const T &select(int k) {
k++;
Node *v = root;
while (!(v->rank() < k && v->rank() + v->count >= k)) v = (k <= v->rank() ? v->child[L] : (k -= v->rank() + v->count, v->child[R]));
return v->splay(), v->value;
}
inline void erase(Node *l, Node *r) {
Node *pre = l->precursor(), *suc = r->successor();
pre->splay(), suc->splay(pre), suc->child[L]->recycle(pool);
pool.recycle(suc->child[L]), suc->child[L] = NULL, suc->maintain(), pre->maintain();
}
inline void erase(Node *v) {
if (v->count > 1) v->count--;
else erase(v, v);
}
inline void erase(const T &l, const T &r) {
Node *vl = find(l), *vr = find(r);
if (!vl) vl = insert(l);
if (!vr) vr = insert(r);
erase(vl, vr);
}
inline int rank(const T &value) {
Node *v = find(value);
if (v) return v->rank();
else {
v = insert(value);
const int ans = v->rank();
return erase(v), ans;
}
}
inline int size() {return root->size-2;}
};
char cmd[30];
int n;
Splay<int, INT_MAX> splay;
int seq[MAXN], len = 0;
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d", &n);
while(n--) {
scanf("%s", cmd);
if (cmd[1] == 'o') {
if (len == 0) {
printf("Invalid\n");
} else {
int v = seq[len-1]; len--;
printf("%d\n", v);
splay.erase(splay.find(v));
}
} else if (cmd[1] == 'e') {
int k = splay.size();
k = (k + 1) >> 1;
if (k == 0) {
printf("Invalid\n");
} else {
printf("%d\n", splay.select(k));
}
} else if (cmd[1] == 'u') {
int x; scanf("%d", &x);
splay.insert(x);
seq[len++] = x;
}
}
return 0;
}
二分+bit
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int MAX_N = 100010;
int bit[MAX_N+1], n;
void update(int i, int x) {
while (i <= n) {
bit[i] += x;
i += i & -i;
}
}
int sum(int i) {
int ans = 0;
while (i) {
ans += bit[i];
i -= i & -i;
}
return ans;
}
int kth(int k) {
int lo = 1, hi = n+1;
while (lo < hi) {
int mi = (lo + hi) >> 1;
if (k <= sum(mi)) {
hi = mi;
} else {
lo = mi + 1;
}
}
return lo;
}
char cmd[20];
int m;
int seq[MAX_N], len = 0;
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d", &m); len = 0;
memset(bit, 0, sizeof(bit)); n = MAX_N;
while (m--) {
scanf("%s", cmd);
if (cmd[1] == 'o') {
if (len == 0) {
printf("Invalid\n");
} else {
int v = seq[len-1]; len--;
printf("%d\n", v);
update(v, -1);
}
} else if (cmd[1] == 'u') {
int x; scanf("%d", &x);
seq[len++] = x;
update(x, 1);
} else if (cmd[1] == 'e') {
int k = len; k = (k + 1) >> 1;
if (k == 0) {
printf("Invalid\n");
} else {
int v = kth(k);
printf("%d\n", v);
}
}
}
return 0;
}