您的位置:首页 > 其它

bzoj 3223 文艺平衡树 - Splay

2017-01-15 20:21 309 查看

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 3884 Solved: 2235
[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

Sample Output

4 3 2 1 5

HINT

N,M<=100000

Source

平衡树

[Submit][Status][Discuss]
    不是特别难,打个lazy标记就行了,详见[Splay]

/**
* bzoj
* Problem#3223
* Accepted
* Time:2012ms
* Memory:4336k
*/
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cctype>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<vector>
using namespace std;
typedef bool boolean;
#define smin(a, b)    (a) = min((a), (b))
#define smax(a, b)    (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = 1;
while(!isdigit((x = getchar())) && x != '-' && x != -1);
if(x == -1)    return;
if(x == '-'){
x = getchar();
aFlag = -1;
}
for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0');
ungetc(x, stdin);
u *= aFlag;
}

template<typename T>
class SplayNode {
public:
T data;
int s;
boolean lazy;
SplayNode* next[2];
SplayNode* father;
SplayNode():s(1), lazy(0){
memset(next, 0, sizeof(next));
}
SplayNode(T data, SplayNode* father):data(data), father(father), s(1), lazy(0){
memset(next, 0, sizeof(next));
}
int cmp(T a){
if(a == data)    return -1;
return (a > data) ? (1) : (0);
}
int getWhich(SplayNode* p){
return (next[0] == p) ? (0) : (1);
}
void maintain(){
s = 1;
for(int i = 0; i < 2; i++)
if(next[i] != NULL)
s += next[i]->s;
}
void pushDown(){
swap(next[0], next[1]);
for(int i = 0; i < 2; i++)
if(next[i] != NULL)
next[i]->lazy ^= 1;
lazy = false;
}
};

template<typename T>
class Splay {
protected:
inline static void rotate(SplayNode<T>*& node, int d){
SplayNode<T> *father = node->father;
SplayNode<T> *newRoot = node->next[d ^ 1];
if(newRoot->lazy)    newRoot->pushDown();
node->next[d ^ 1] = newRoot->next[d];
node->father = newRoot;
newRoot->next[d] = node;
newRoot->father = father;
if(node->next[d ^ 1] != NULL)    node->next[d ^ 1]->father = node;
if(father != NULL)    father->next[father->getWhich(node)] = newRoot;
node->maintain();
node->father->maintain();
}

static SplayNode<T>* insert(SplayNode<T>*& node, SplayNode<T>* father, T data){
if(node == NULL){
node = new SplayNode<T>(data, father);
return node;
}
int d = node->cmp(data);
if(d == -1)    return NULL;
SplayNode<T>* res = insert(node->next[d], node, data);
if(res != NULL)    node->maintain();
return res;
}

static SplayNode<T>* findKth(SplayNode<T>*& node, int k){
if(node->lazy)    node->pushDown();
int ls = (node->next[0] != NULL) ? (node->next[0]->s) : (0);
if(k >= ls + 1 && k <= ls + 1)    return node;
if(k <= ls)    return findKth(node->next[0], k);
return findKth(node->next[1], k - ls - 1);
}

public:
SplayNode<T> *root;

Splay(){    }

inline void splay(SplayNode<T>* node, SplayNode<T>* father){
if(node == father)    return;
while(node->father != father){
SplayNode<T>* f = node->father;
int fd = f->getWhich(node);
SplayNode<T>* ff = f->father;
if(ff == father){
rotate(f, fd ^ 1);
break;
}
int ffd = ff->getWhich(f);;
if(ffd == fd){
rotate(ff, ffd ^ 1);
rotate(f, fd ^ 1);
}else{
rotate(f, fd ^ 1);
rotate(ff, ffd ^ 1);
}
}
if(father == NULL)
root = node;
}

inline SplayNode<T>* insert(T data){
SplayNode<T>* res = insert(root, NULL, data);
if(res != NULL)    splay(res, NULL);
return res;
}

inline SplayNode<T>* findKth(int k, SplayNode<T>* father){
if(k <= 0 || k > root->s)    return NULL;
SplayNode<T>* p = findKth(root, k);
splay(p, father);
return p;
}

SplayNode<T>* split(int from, int end){
if(from > end)    return NULL;
if(from == 1 && end == root->s){
findKth(1, NULL);
return this->root;
}
if(from == 1){
findKth(end + 1, NULL);
findKth(from, root);
return root->next[0];
}
if(end == root->s){
findKth(from - 1, NULL);
findKth(end, root);
return root->next[1];
}
findKth(end + 1, NULL);
findKth(from - 1, root);
return root->next[0]->next[1];
}

void out(SplayNode<T>* node){
if(node == NULL)    return;
if(node->lazy)    node->pushDown();
out(node->next[0]);
printf("%d ", node->data);
out(node->next[1]);
}

void debugOut(SplayNode<T>* node){    //调试使用函数,打印Splay
if(node == NULL)    return;
cout << node->data << "(" << node->s << "," << ((node->father == NULL) ? (-9999) : (node->father->data)) << "," << node->lazy << "){";
debugOut(node->next[0]);
cout <<    ",";
debugOut(node->next[1]);
cout << "}";
}
};

int n, m;
Splay<int> s;

int main(){
readInteger(n);
readInteger(m);
for(int i = 1; i <= n; i++){
s.insert(i);
}
for(int i = 1, a, b; i<= m; i++){
readInteger(a);
readInteger(b);
if(a == b)    continue;
SplayNode<int>* p = s.split(a, b);
p->lazy ^= 1;
}
s.out(s.root);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: