BZOJ 3223: Tyvj 1729 文艺平衡树(splay)
速度居然进前十了...第八...
splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转
----------------------------------------------------------------------------------------
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define rep(i, n) for(int i = 0; i < n; ++i)
#define clr(x, c) memset(x, c, sizeof(x))
using namespace std;
const int maxn = 100000 + 5;
int n;
struct node *null, *pt;
struct node {
node* ch[2];
int v, s;
bool flip;
node(int _v = 0) : v(_v), s(1), flip(0) {
ch[0] = ch[1] = null;
}
inline int cmp(int k) const {
k -= ch[0]->s;
if(k == 1) return -1;
return k <= 0 ? 0 : 1;
}
inline void maintain() {
s = ch[0]->s + ch[1]->s + 1;
}
inline void pushdown() {
if(flip) {
flip = 0;
swap(ch[0], ch[1]);
ch[0]->flip ^= 1;
ch[1]->flip ^= 1;
}
}
void *operator new (size_t) { return pt++; }
};
node* root;
node N[maxn], Null;
void rotate(node* &o, int d) {
node* k = o->ch[d^1];
o->ch[d^1] = k->ch[d];
k->ch[d] = o;
o->maintain(); k->maintain();
o = k;
}
void splay(node* &o, int k) {
o->pushdown();
int d = o->cmp(k);
if(d == 1) k -= o->ch[0]->s + 1;
if(d != -1) {
node* p = o->ch[d];
p->pushdown();
int d2 = p->cmp(k);
int k2 = d2 ? k - p->ch[0]->s - 1 : k;
if(d2 != -1) {
splay(p->ch[d2], k2);
d == d2 ? rotate(o, d^1) : rotate(o->ch[d], d);
}
rotate(o, d^1);
}
}
node* build(int l, int r) {
if(l >= r) return null;
int m = (l + r) >> 1;
node* o = new node(m);
if(l < m) o->ch[0] = build(l, m);
if(m + 1 < r) o->ch[1] = build(m + 1, r);
o->maintain();
return o;
}
void init() { pt = N; null = &Null; null->s = 0; root = build(0, n + 2); }
void dfs(node* o) {
if(o == null) return;
o->pushdown();
dfs(o->ch[0]);
if(o->v >= 1 && o->v <= n) printf("%d ",o->v);
dfs(o->ch[1]);
}
inline int read() {
int ans = 0, f = 1;
char c = getchar();
while(!isdigit(c)) {
if(c == '-') f = -1;
c = getchar();
}
while(isdigit(c)) {
ans = ans * 10 + c - '0';
c = getchar();
}
return f * ans;
}
int main() {
n = read();
int m = read();
init();
while(m--) {
int l = read(), r = read();
if(l == r) continue;
splay(root, l);
splay(root->ch[1], r + 1 - root->ch[0]->s);
root->ch[1]->ch[0]->flip ^= 1;
}
dfs(root);
return 0;
}
----------------------------------------------------------------------------------------
3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1675 Solved: 931
[Submit][Status][Discuss]
Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
Input
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
Output
输出一行n个数字,表示原始序列经过m次变换后的结果
Sample Input
5 3
1 3
1 3
1 4
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000
Source