您的位置:首页 > 其它

BZOJ 3223 文艺平衡树 【Splay】

2015-12-03 16:22 429 查看
flip是个翻转标记辣 用重载的new可以不用再去动态开辟了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
using namespace std;

const int Maxn(100005);

int n,m;

struct Node *null,*pt;
struct Node
{
Node *ch[2];
int v,s;
bool flip;
Node (int __ = 0) : v(__),s(1),flip(false)
{
ch[0] = ch[1] = null;
}
int cmp(int k) const
{
k -= ch[0] -> s;
if (k == 1) return -1;
return k <= 0 ? 0 : 1;
}
void maintain()
{
s = ch[0] -> s + ch[1] -> s + 1;
}
void pushdown()
{
if (flip)
{
flip = false;
swap(ch[0],ch[1]);
ch[0] -> flip ^= 1;
ch[1] -> flip ^= 1;
}
}
void *operator new (size_t) { return pt++; }

}*Root,N[Maxn],Null;

inline long long Read()
{
long long Ret = 0;
char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) { Ret = Ret * 10 + c - '0'; c = getchar(); }
return Ret;
}

inline void Rotate(Node *&o,const 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 MidOrder(Node *Root)
{
if (Root == null) return ;
Root -> pushdown();
MidOrder(Root -> ch[0]);
if (Root -> v >= 1 && Root -> v <= n) cout << Root -> v << ' ';
MidOrder(Root -> ch[1]);
}

int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n = Read(); m = Read();
Init();
while (m--)
{
int l,r;
cin >> l >> r;
if (l == r) continue;
Splay(Root,l);
Splay(Root -> ch[1],r + 1 - Root -> ch[0] -> s);
Root -> ch[1] -> ch[0] -> flip ^= 1;
}
MidOrder(Root);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Splay