题目链接:uva 11922 - Permutation Transformer
题目大意:给定一个序列,每次操作取出区间a~b,翻转后放到末尾,随后输出序列。
解题思路:就是伸展树,对于每个节点设一个flip,表示是否为翻转转态。每次将a旋转到根,然后分裂,再将b翻转到根,分裂,然后将mid翻转放到最后。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node {
int val, sum, flip;
Node* cid[2];
Node(int val = 0);
int cmp (int v);
void maintain();
void pushdown();
};
void rotate (Node* &o, int d);
void build(Node* &o, int l, int r);
void put(Node* &o);
void split (Node* o, int k, Node* &l, Node* & r);
Node* merge (Node* l, Node* r);
void splay(Node* &o, int k);
int main () {
int n, m, x, y;
while (scanf("%d%d", &n, &m) == 2) {
Node* root = NULL;
Node *l, *mid, *r, *o;
build(root, 0, n);
for (int i = 0; i < m; i++) {
scanf("%d%d", &x, &y);
split(root, x, l, o);
split(o, y - x + 1, mid, r);
mid->flip ^= 1;
root = merge(merge(l, r), mid);
}
put(root);
}
return 0;
}
void splay(Node* &o, int k) {
o->pushdown();
int d = o->cmp(k);
if (d == 1) k -= (o->cid[0] == NULL ? 0 : o->cid[0]->sum) + 1;
if (d != -1) {
Node* p = o->cid[d];
p->pushdown();
int d2 = p->cmp(k);
int k2 = (d2 == 0 ? k : k - (p->cid[0] == NULL ? 0 : p->cid[0]->sum) - 1);
if (d2 != -1) {
splay(p->cid[d2], k2);
if (d == d2)
rotate(o, d^1);
else
rotate(o->cid[d], d);
}
rotate(o, d^1);
}
}
Node* merge (Node* l, Node* r) {
splay(l, l->sum);
l->cid[1] = r;
l->maintain();
return l;
}
void split (Node* o, int k, Node* &l, Node* & r) {
splay(o, k);
l = o;
r = o->cid[1];
o->cid[1] = NULL;
l->maintain();
}
void build(Node* &o, int l, int r) {
if (l > r)
return;
int mid = (l + r) / 2;
o = new Node(mid);
build(o->cid[0], l, mid - 1);
build(o->cid[1], mid + 1, r);
o->maintain();
}
void rotate (Node* &o, int d) {
Node* k = o->cid[d^1];
o->cid[d^1] = k->cid[d];
k->cid[d] = o;
o->maintain();
k->maintain();
o = k;
}
void put(Node* &o) {
o->pushdown();
if (o->cid[0] != NULL) put(o->cid[0]);
if (o->val)
printf("%d\n", o->val);
if (o->cid[1] != NULL) put(o->cid[1]);
delete o;
o = NULL;
}
Node::Node (int val) {
sum = 1;
flip = 0;
this->val = val;
cid[0] = cid[1] = NULL;
}
int Node::cmp (int v) {
int d = v - (cid[0] == NULL ? 0 : cid[0]->sum);
if (d == 1) return -1;
return d <= 0 ? 0 : 1;
}
void Node::pushdown() {
if (flip) {
flip = 0;
swap(cid[0], cid[1]);
if (cid[0] != NULL)
cid[0]->flip = !cid[0]->flip;
if (cid[1] != NULL)
cid[1]->flip = !cid[1]->flip;
}
}
void Node::maintain () {
sum = 1;
if (cid[0] != NULL) sum += cid[0]->sum;
if (cid[1] != NULL) sum += cid[1]->sum;
}
void remove (Node* &o) {
if (o->cid[0] != NULL) remove(o->cid[0]);
if (o->cid[1] != NULL) remove(o->cid[1]);
delete o;
o = NULL;
}
时间: 2024-10-03 00:50:46