您的位置:首页 > 其它

BZOJ3223文艺平衡树

2016-03-14 21:17 423 查看
3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec Memory Limit: 128 MB

Submit: 2705 Solved: 1529

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

平衡树

splay模板题。。

终于打了一次splay。。

附上本蒟蒻的代码:

#include<cstdio>
#include<iostream>
using namespace std;
#define MAXN 100001
int n,m,sz,rt,father[MAXN],c[MAXN][2],id[MAXN],size[MAXN];
bool rev[MAXN];

int read()
{
int w=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9')
{
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0' && ch<='9')
w=w*10+ch-'0',ch=getchar();
return w*f;
}

void update(int s)
{
int l=c[s][0],r=c[s][1];
size[s]=size[l]+size[r]+1;
}

void pushdown(int s)
{
int l=c[s][0],r=c[s][1];
if (rev[s])
{
swap(c[s][0],c[s][1]);
rev[l]^=1,rev[r]^=1;
rev[s]=0;
}
}

void rotate(int x,int &s)
{
int y=father[x],z=father[y],l,r;
if (c[y][0]==x) l=0;
else l=1;
r=l^1;
if (y==s) s=x;
else
if (c[z][0]==y)
c[z][0]=x;
else
c[z][1]=x;
father[x]=z,father[y]=x,father[c[x][r]]=y;
c[y][l]=c[x][r],c[x][r]=y;
update(y),update(x);
}

void splay(int x,int &s)
{
int y,z;
while (x!=s)
{
y=father[x],z=father[y];
if (y!=s)
if (c[y][0]==x^c[z][0]==y)
rotate(x,s);
else
rotate(y,s);
rotate(x,s);
}
}

int find(int s,int rank)
{
pushdown(s);
int l=c[s][0],r=c[s][1];
if (size[l]+1==rank)
return s;
else
if (size[l]>=rank)
return find(l,rank);
else
return find(r,rank-size[l]-1);
}

void rever(int l,int r)
{
int x=find(rt,l),y=find(rt,r+2);
splay(x,rt);splay(y,c[x][1]);
int z=c[y][0];
rev[z]^=1;
}

void build(int l,int r,int f)
{
if (l>r) return;
int now=id[l],last=id[f];
if (l==r)
{
father[now]=last,size[now]=1;
if (l<f) c[last][0]=now;
else c[last][1]=now;
return;
}
int mid=(l+r)>>1;
now=id[mid];
build(l,mid-1,mid);build(mid+1,r,mid);
father[now]=last,update(mid);
if (mid<f) c[last][0]=now;
else c[last][1]=now;
}

int main()
{
int i,l,r;
n=read(),m=read();
for (i=1;i<=n+2;i++)
id[i]=++sz;
build(1,n+2,0);
rt=(n+3)>>1;
for (i=1;i<=m;i++)
{
l=read(),r=read();
rever(l,r);
}
for (i=2;i<=n+1;i++)
printf("%d ",find(rt,i)-1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: