1. 反转一个区间

# 代码

#include <bits/stdc++.h>
using namespace std;
int n, m, sz, rt;
#ifdef DEBUG
const int maxn = 100;
#else
const int maxn = 100005;
#endif
int fa[maxn], c[maxn][2], id[maxn];
int size[maxn];
bool rev[maxn];
void pushup(int k) {
int l = c[k][0], r = c[k][1];
size[k] = size[l] + size[r] + 1;
}
void pushdown(int k) {
int &l = c[k][0], &r = c[k][1];
if (rev[k]) {
swap(l, r);
rev[l] ^= 1;
rev[r] ^= 1;
rev[k] = 0;
}
}
void zig(int x, int &k) {         // do one zig
int y = fa[x], z = fa[y], l, r; // y:father z:grandfather
if (c[y][0] == x) {             // zig
l = 0;
} else
l = 1; // zag
r = l ^ 1;
if (y == k)
k = x; // single zig
else {   // update grandfather
if (c[z][0] == y)
c[z][0] = x; // zig-zig
else
c[z][1] = x;
}
fa[x] = z;
fa[y] = x;
fa[c[x][r]] = y;
c[y][l] = c[x][r];
c[x][r] = y;
pushup(y);
pushup(x);
}
void splay(int x, int &k) {
while (x != k) {
int y = fa[x], z = fa[y];
if (y != k) {
if (c[y][0] == x ^ c[z][0] == y) // diff:zig-zag or zag-zig
zig(x, k);
else // same:zig-zig or zag-zag
zig(y, k);
}
zig(x, k);
}
}
int find(int k, int rank) {
pushdown(k);
int l = c[k][0], r = c[k][1];
if (size[l] + 1 == rank)
return k;
else if (size[l] >= rank)
return find(l, rank);
else
return find(r, rank - size[l] - 1);
}

void rever(int l, int r) {
int x = find(rt, l), y = find(rt, r + 2);
splay(x, rt);
splay(y, c[x][1]);
int z = c[y][0];
rev[z] ^= 1;
}
void build(int l, int r, int f) { // f:last node
if (l > r)
return;
int now = id[l], last = id[f];
if (l == r) {
fa[now] = last;
size[now] = 1;
if (l < f)
c[last][0] = now;
else
c[last][1] = now;
return;
}
int mid = (l + r) >> 1;
now = id[mid];
build(l, mid - 1, mid);
build(mid + 1, r, mid);
fa[now] = last;
pushup(mid);
if (mid < f) {
c[last][0] = now;
} else
c[last][1] = now;
return;
}

int main() {
#ifdef DEBUG
freopen("input", "r", stdin);
#endif
scanf("%d %d", &n, &m);
for (int i = 1; i <= n + 2; i++)
id[i] = ++sz;
build(1, n + 2, 0);
rt = (n + 3) >> 1;
for (int i = 1; i <= m; i++) {
int l, r;
scanf("%d %d", &l, &r);
rever(l, r);
}
for (int i = 2; i <= n + 1; i++) {
printf("%d ", find(rt, i) - 1);
}
return 0;
}


posted on 2017-02-27 10:09  蒟蒻konjac  阅读(934)  评论(0编辑  收藏  举报