题目描述
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是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
#include<iostream>
#include<cstdio>
using namespace std;
const int MAX=100010;
struct splay_tree{
int lef,rig,p,sz;
bool flag;
}t[MAX];
int root,n,m;
void update(int x){
t[x].sz=t[t[x].lef].sz+t[t[x].rig].sz+1;
}
void swap(int &x,int &y){
int tt=x;x=y;y=tt;
}
void change_relation(int x,int y,bool d){
if (d) t[x].rig=y;
else t[x].lef=y;
t[y].p=x;
}
bool get_direct(int x){
return x==t[t[x].p].rig;
}
void pushdown(int x){
if (t[x].flag){
swap(t[x].lef,t[x].rig);//交换子树
t[t[x].lef].flag^=1; //标记翻转
t[t[x].rig].flag^=1;
t[x].flag=false; //标记清除
}
}
void rotate(int x){ //智慧地将左右旋结合
int father=t[x].p;bool d=get_direct(x);
if (father==root) root=x,t[x].p=0;
else change_relation(t[father].p,x,get_direct(father));
if (d) change_relation(father,t[x].lef,d);
else change_relation(father,t[x].rig,d);
change_relation(x,father,!d);
update(father);
}
void splay(int x,int y){
if (x==y) return ;
for (int father;(father=t[x].p)!=y; ){
if (t[father].p==y) {rotate(x);break;}
if (get_direct(x)==get_direct(father)) rotate(father);
else rotate(x);
rotate(x);
}
update(x);
}
int find_maxk(int k){ //找出第k数
--k;
int p=root;pushdown(p);
while (k!=t[t[p].lef].sz){
if (t[t[p].lef].sz<k){
k-=t[t[p].lef].sz+1;p=t[p].rig;
}else p=t[p].lef;
pushdown(p);
}
return p;
}
int build_tree(int l,int r){
if (l>r) return 0;
int m=(l+r)>>1;
change_relation(m,build_tree(l,m-1),false);
change_relation(m,build_tree(m+1,r),true);
t[m].flag=0;
update(m);return m;
}
void exchange(int l,int r){ //翻转区间
int direct1=find_maxk(l),direct2=find_maxk(r+2);
splay(direct1,0);
splay(direct2,root);
t[t[direct2].lef].flag^=1;
}
void dfs(int rt){
if (rt==0) return ;
pushdown(rt);
dfs(t[rt].lef);
if (1<rt&&rt<n+2) printf("%d ",rt-1);
dfs(t[rt].rig);
}
int main(){
cin >>n>>m;int ll,rr;
root=build_tree(1,n+2);
for (int i=1;i<=m;++i){
scanf("%d%d",&ll,&rr);
exchange(ll,rr);
}
dfs(root);
return 0;
}