题目描述
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
输入输出格式
输入格式:
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
输出格式:
输出一行n个数字,表示原始序列经过m次变换后的结果
输入输出样例
输入样例#1:
5 3
1 3
1 3
1 4
输出样例#1:
4 3 2 1 5
说明
N,M<=100000
【分析】
比起上一道题,这题简直菜爆了…
一道模板题,大家可以参考洛谷的题解
【代码】
//bzoj 文艺平衡树
#include<iostream>
#include<cstring>
#include<cstdio>
#define inf 1e9+7
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=100005;
int n,m,sz,opt,root;
int f[mxn],ch[mxn][2],data[mxn],key[mxn],mark[mxn],size[mxn];
inline void clear(int x)
{
f[x]=ch[x][0]=ch[x][1]=key[x]=mark[x]=0;
}
inline void update(int x)
{
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
inline int get(int x)
{
if(ch[f[x]][0]==x) return 0;return 1;
}
inline void pushdown(int x)
{
if(x && mark[x])
{
mark[x]=0;
mark[ch[x][0]]^=1;
mark[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
}
}
inline void rotate(int x)
{
int old=f[x],elder=f[old],which=get(x);
pushdown(old);pushdown(x);
ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
f[old]=x,ch[x][which^1]=old;
f[x]=elder;
if(elder) ch[elder][ch[elder][1]==old]=x;
update(old),update(x);
}
inline void splay(int x,int lastfa)
{
for(int fa;(fa=f[x])!=lastfa;rotate(x))
if(f[fa]!=lastfa) rotate(get(x)==get(fa)?fa:x);
if(!lastfa) root=x;
}
inline int build(int fa,int l,int r)
{
if(l>r) return 0;
int mid=l+r>>1,now=++sz;
key[now]=data[mid],f[now]=fa,mark[now]=0;
ch[now][0]=build(now,l,mid-1);
ch[now][1]=build(now,mid+1,r);
update(now);
return now;
}
inline void print(int now)
{
pushdown(now);
if(ch[now][0]) print(ch[now][0]);
if(key[now]>-inf && key[now]<inf) printf("%d ",key[now]);
if(ch[now][1]) print(ch[now][1]);
}
inline int number(int x)
{
int now=root;
while(1)
{
pushdown(now);
if(x<=size[ch[now][0]]) now=ch[now][0];
else
{
x=x-size[ch[now][0]]-1;
if(!x) return now;
now=ch[now][1];
}
}
}
int main()
{
int i,j,k,x,y;
scanf("%d%d",&n,&m);
fo(i,2,n+1) data[i]=i-1;
data[1]=-inf,data[n+2]=inf;
root=build(0,1,n+2);
fo(i,1,m)
{
scanf("%d%d",&x,&y);
x=number(x),y=number(y+2);
splay(x,0);
splay(y,x);
mark[ch[ch[root][1]][0]]^=1;
}
print(root);
return 0;
}