3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3321 Solved: 1887
[ 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
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
int root,sz,n,m;
int ch[100010][5],f[100010],size[100010],key[100010],a[100010],delta[100010];
void swap(int &x,int &y)
{
int t;
t=x; x=y; y=t;
}
void updata(int x)
{
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
int get(int x)
{
return ch[f[x]][1]==x;
}
void pushdown(int x)
{
if (!x) return;
if (!delta[x]) return;
delta[ch[x][0]]^=1;
delta[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
delta[x]=0;
}
int build (int l,int r,int fa)
{
if (l>r) return 0;
int mid=(l+r)>>1;
int now=++sz;
ch[now][0]=build(l,mid-1,now);
ch[now][1]=build(mid+1,r,now);
f[now]=fa; delta[now]=0;
key[now]=a[mid];size[now]=size[ch[now][1]]+size[ch[now][0]]+1;
return now;
}
int find(int x)
{
int now=root;
while (true)
{
pushdown(now);
if (x<=size[ch[now][0]])
now=ch[now][0];
else
{
x-=(size[ch[now][0]]+1);
if (x==0) return now;
now=ch[now][1];
}
}
return -1;
}
void rotate(int x)
{
pushdown(f[x]); pushdown(x);
int fa=f[x],oldfa=f[fa],which=get(x);
ch[fa][which]=ch[x][which^1]; f[ch[x][which^1]]=fa;
ch[x][which^1]=fa; f[fa]=x;
f[x]=oldfa;
if (oldfa)
ch[oldfa][ch[oldfa][1]==fa]=x;
updata(x); updata(fa);
}
void splay (int x,int l)
{
pushdown(x);
for (int fa;(fa=f[x])!=l;rotate(x))
if (f[fa]!=l)
rotate((get(fa)==get(x))?fa:x);
if (l==0) root=x;
}
void print(int now)
{
pushdown(now);
if (ch[now][0]) print(ch[now][0]);
if (key[now]!=1000000000&&key[now]!=-1000000000)
printf("%d ",key[now]);
if (ch[now][1]) print(ch[now][1]);
}
int main()
{
scanf("%d%d",&n,&m);
a[1]=-1000000000; a[n+2]=1000000000;
for (int i=1;i<=n;i++)
a[i+1]=i;
root=build(1,n+2,0);
for (int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
int aa=find(x);
int bb=find(y+2);
splay(aa,0);
splay(bb,aa);
delta[ch[ch[root][1]][0]]^=1;
}
print(root);
printf("\n");
}