您的位置:首页 > 其它

bzoj 3223(splay)

2016-01-06 19:31 295 查看

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec Memory Limit: 128 MB

Submit: 2348 Solved: 1312

[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

splay裸题

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<iostream>

#include<cmath>

using namespace std;

int n,m,size,root;

struct ss

{

int l,r,zhi,fa,rever,size;

}messi[110000];

inline int read()

{

char y; int x=0; y=getchar();

while (y<'0' || y>'9') y=getchar();

while (y>='0' && y<='9') { x=x*10+int (y)-48; y=getchar();};

return x;

}

void pushup(int k)

{

int l=messi[k].l; int r=messi[k].r;

messi[k].size=messi[l].size+messi[r].size+1;

}

void build(int fa,int l,int r,int &k)

{

int mid=(l+r)/2;

++size; k=size;

messi[k].zhi=mid-1; messi[k].rever=0; messi[k].fa=fa; messi[k].size=r-l+1;

if (l==r) return;

if (l!=mid) build(k,l,mid-1,messi[k].l);

if (r!=mid) build(k,mid+1,r,messi[k].r);

}

void pushdown(int k)

{

int l=messi[k].l; int r=messi[k].r;

if (messi[k].rever)

{

swap(messi[k].l,messi[k].r);

messi[l].rever^=1; messi[r].rever^=1;

messi[k].rever=0;

}

}

void rotate(int x,int &k)

{

int y=messi[x].fa;

int z=messi[y].fa;

if (y==k) k=x; else

{

if (messi[z].l==y) messi[z].l=x;else

messi[z].r=x;

}

if (messi[y].l==x)

{

messi[messi[x].r].fa=y;

messi[y].l=messi[x].r; messi[x].r=y;

messi[x].fa=messi[y].fa; messi[y].fa=x;

}else

{

messi[messi[x].l].fa=y;

messi[y].r=messi[x].l; messi[x].l=y;

messi[x].fa=messi[y].fa; messi[y].fa=x;

}

pushup(y); pushup(x);

}

void splay(int x,int &k)

{

while (x!=k)

{

int y=messi[x].fa; int z=messi[y].fa;

if (y!=k)

{

if ((messi[y].l==x)^(messi[z].l==y)) rotate(x,k);else

rotate(y,k);

}

rotate(x,k);

}

}

int find(int k,int rank)

{

if (messi[k].rever) pushdown(k); int l=messi[k].l;

if (messi[messi[k].l].size+1==rank) return k;

if (messi[l].size<rank) return find(messi[k].r,rank-messi[l].size-1);

else return find(l,rank);

}

void work(int l,int r)

{

int x=find(root,l-1); int y=find(root,r+1);

splay(x,root); splay(y,messi[root].r);

int u=messi[y].l;

messi[u].rever^=1;

}

int main()

{

n=read(); m=read();

n=n+2; size=0;

build(0,1,n,root);

for (int i=1;i<=m;++i)

{

int l,r;

l=read()+1; r=read()+1;

work(l,r);

}

for (int i=2;i<=n-1;++i)

printf("%d ",messi[find(root,i)].zhi);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: