您的位置:首页 > 其它

BZOJ1552 [Cerc2007]robotic sort

2015-05-01 21:34 363 查看
支持区间最小值查询,区间翻转的数据结构

直接上treap板子啊亲!没了。。。

只是为了存板用的2333

/**************************************************************
Problem: 1552
User: rausen
Language: C++
Result: Accepted
Time:2456 ms
Memory:5572 kb
****************************************************************/

#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 1e5 + 5;
const int inf = 1e9;

inline int read();
inline void print(int, char);

int n, a
;

namespace treap {
struct node;
node *null, *root;

struct node {
node *ls, *rs;
int sz, v;
bool rev;
int mn, wmn;

node() {}
node (int _v) : v(_v) {
ls = rs = null;
rev = 0, sz = 1;
mn = _v, wmn = -1;
}

#define Len (1 << 16)
void* operator new(size_t, int _v) {
static node *mempool, *c;
if (c == mempool)
mempool = (c = new node[Len]) + Len;
*c = node(_v);
return c++;
}
#undef Len

inline void push() {
if (rev) {
swap(ls, rs);
ls -> rev ^= 1, rs -> rev ^= 1;
if (wmn != -1) wmn ^= 1;
rev = 0;
}
}
inline void update() {
sz = ls -> sz + rs -> sz + 1;
wmn = -1, mn = v;
if (ls -> mn <= mn) wmn = 0, mn = ls -> mn;
if (rs -> mn < mn) wmn = 1, mn = rs -> mn;
}
};

inline unsigned int rand() {
static unsigned int res = 2333;
return res += res << 2 | 1;
}
inline int random(int x, int y) {
return rand() % (x + y) < x;
}

void build(node *&p, int *a, int l, int r) {
if (l > r) return;
p = new(a[l + r >> 1])node;
if (l == r) return;
build(p -> ls, a, l, (l + r >> 1) - 1);
build(p -> rs, a, (l + r >> 1) + 1, r);
p -> update();
}

void merge(node *&p, node *x, node *y) {
if (x == null || y == null) {
p = x == null ? y : x;
p -> update();
return;
}
if (random(x -> sz, y -> sz)) {
x -> push(), p = x;
merge(p -> rs, x -> rs, y);
p -> update();
} else {
y -> push(), p = y;
merge(p -> ls, x, y -> ls);
p -> update();
}
}

void split(node *p, node *&x, node *&y, int k) {
if (!k) {
x = null, y = p;
return;
}
if (k == p -> sz) {
x = p, y = null;
return;
}
p -> push();
if (p -> ls -> sz >= k) {
y = p;
split(p -> ls, x, y -> ls, k);
y -> update();
} else {
x = p;
split(p -> rs, x -> rs, y, k - p -> ls -> sz - 1);
x -> update();
}
}

inline void reverse(int l, int r) {
static node *x, *y, *z;
split(root, x, z, l - 1);
split(z, y, z, r - l + 1);
y -> rev ^= 1;
root = x;
merge(root, root, y);
merge(root, root, z);
}

inline int get_min(node *p) {
p -> push();
if (p -> wmn == 0) return get_min(p -> ls);
if (p -> wmn == -1) return p -> ls -> sz + 1;
return p -> ls -> sz + 1 + get_min(p -> rs);
}
inline void modify(node *p, int k, int _v) {
p -> push();
if (p -> ls -> sz + 1 == k) p -> v = _v;
else if (p -> ls -> sz >= k) modify(p -> ls, k, _v);
else modify(p -> rs, k - p -> ls -> sz - 1, _v);
p -> update();
}
};

int tmp
, tmp2
;
inline bool cmp(int x, int y) {
return tmp[x] == tmp[y] ? x < y : tmp[x] < tmp[y];
}

int main() {
int i, x;
using namespace treap;
n = read();
for (i = 1; i <= n; ++i) tmp[i] = read(), tmp2[i] = i;
sort(tmp2 + 1, tmp2 + n + 1, cmp);
for (i = 1; i <= n; ++i) a[tmp2[i]] = i;
null = new(inf)node;
null -> ls = null -> rs = null, null -> sz = 0;
build(root, a, 1, n);
for (i = 1; i <= n; ++i) {
print(x = get_min(root), i == n ? '\n' : ' ');
reverse(i, x);
modify(root, i, inf);
}
return 0;
}

inline int read() {
static int x;
static char ch;
x = 0, ch = getchar();
while (ch < '0' || '9' < ch)
ch = getchar();
while ('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x;
}

inline void print(int t, char ch = ' ') {
static int tot, pr[10];
tot = 0;
while (t)
pr[++tot] = t % 10, t /= 10;
if (!tot) putchar('0');
while (tot) putchar(pr[tot--] + '0');
putchar(ch);
}


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