3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5402 Solved: 3196
[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
正如sourse所说这是一道平衡树的题目,treep对于区间维护好像并不太擅长
我们用splay,splay改变序列是靠中序遍历的不同,区间反转维护lazy标记即可
#include <bits/stdc++.h>
#define ll long long
#define inf 10000100
using namespace std;
inline int read(){
int x=0;int f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=1e6+10;
namespace zhangenming{
int son[MAXN][2],n,m,siz[MAXN],rev[MAXN]={},fa[MAXN],a[MAXN],tot,key[MAXN],root=0;
inline void push_up(int x){
siz[x]=siz[son[x][1]]+siz[son[x][0]]+1;
}
inline int get(int x){
return x==son[fa[x]][1];
}
inline void push_down(int x){
if(!x||!rev[x]) return;
rev[son[x][1]]^=1;rev[son[x][0]]^=1;
swap(son[x][1],son[x][0]);
rev[x]=0;
}
inline void rote(int x){
push_down(x);push_down(fa[x]);
int oldl=fa[x];int wei=get(x);int oldf=fa[fa[x]];
son[oldl][wei]=son[x][wei^1];fa[son[oldl][wei]]=oldl;
fa[x]=oldf;fa[oldl]=x;son[x][wei^1]=oldl;
if(oldf){
son[oldf][son[oldf][1]==oldl]=x;
}
push_up(x);push_up(oldl);
}
inline int build(int leftt,int rightt,int root){
if(leftt>rightt) return 0;
int mid=(rightt+leftt)>>1;
int now=++tot;
rev[now]=0;fa[now]=root;key[now]=a[mid];
int lefttchild=build(leftt,mid-1,now);
int righttchild=build(mid+1,rightt,now);
son[now][0]=lefttchild;son[now][1]=righttchild;push_up(now);
return now;
}
inline void splay(int xx,int tal){
for(int f;(f=fa[xx])!=tal;rote(xx)){
if(fa[f]!=tal){
rote(get(f)==get(xx)?f:xx);
}
}
if(tal==0) root=xx;
}
inline int find(int xx){
int now=root;
while(1){
push_down(now);
if(xx==0) return now;
if(xx<=siz[son[now][0]]){
now=son[now][0];
}
else{
xx-=siz[son[now][0]]+1;
if(xx==0) return now;
now=son[now][1];
}
}
}
void print(int root){
push_down(root);
if(son[root][0]) print(son[root][0]);
if(key[root]!=inf&&key[root]!=-inf) printf("%d ",key[root]);
if(son[root][1]) print(son[root][1]);
}
void init(){
n=read();m=read();
a[1]=inf;a[n+2]=-inf;
for(int i=1;i<=n;i++){
a[i+1]=i;
}
root=build(1,n+2,0);
}
inline void printt(){
for(int i=1;i<=n+2;i++){
cout<<son[i][0]<<' '<<son[i][1]<<endl;
}
}
void solve(){
while(m--){
int xx=read();int yy=read();
if(xx>=yy) continue;
xx=find(xx);yy=find(yy+2);
splay(xx,0);splay(yy,xx);
rev[son[son[root][1]][0]]^=1;
}
print(root);
}
}
int main(){
//freopen("All.in","r",stdin);
//freopen("a.out","w",stdout);
using namespace zhangenming;
init();
solve();
return 0;
}