1. 程式人生 > >[BZOJ]3223 文藝平衡樹 區間翻轉

[BZOJ]3223 文藝平衡樹 區間翻轉

3223: Tyvj 1729 文藝平衡樹

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 4861  Solved: 2851
[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

Sample Output

4 3 2 1 5

HINT



N,M<=100000

Source

平衡樹



HOME Back

普通的區間翻轉而已.

#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=100005;
int siz[maxn],c[maxn][2],newone,s[maxn],rev[maxn],fa[maxn],n,m,tot,root,l,r,w[maxn];
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    register int x=0,f=1;
    register char ch=nc();
    while(ch<'0'||ch>'9'){if(ch=='-')f*=-1;ch=nc();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=nc();
    return f*x;
}
inline int newnode(){
    newone=++tot;
    siz[newone]=fa[newone]=c[newone][0]=c[newone][1]=0;
    return newone;
}
inline void update(int x){
    if(!x) return;
    siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;
}
inline void pushdown(int x){
    if(!x) return;
	if(rev[x]){
	   rev[x]^=1,rev[c[x][0]]^=1,rev[c[x][1]]^=1;
	   swap(c[x][0],c[x][1]);
	}
}
inline void rotate(int x,int &_wanna){
    int y=fa[x],z=fa[y];
    int l=(c[y][0]!=x),r=l^1;
    if(y!=_wanna) c[z][c[z][0]!=y]=x;
    else _wanna=x;
    fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
    c[y][l]=c[x][r],c[x][r]=y;
    update(y),update(x);
}
inline void splay(int x,int &_wanna){
    int top=0;
	for(int i=x;i;i=fa[i]) s[++top]=i;
	for(int i=top;i;i--) pushdown(s[i]);
	for(int f;x!=_wanna;rotate(x,_wanna))
     if((f=fa[x])!=_wanna)
       rotate(((c[fa[f]][0]==f^c[f][0]==x)?x:f),_wanna);
}
int find(int k,int x){
	pushdown(k);
    if(x-1==siz[c[k][0]]) return k;
    if(x>siz[c[k][0]]+1) return find(c[k][1],x-siz[c[k][0]]-1);
    else return find(c[k][0],x);
}
void build(int lf,int rg,int who){
	int mid=(lf+rg)>>1;
	w[who]=mid;
	if(lf==rg) {siz[who]=1;return;}
	if(lf<mid) {c[who][0]=newnode();fa[c[who][0]]=who;build(lf,mid-1,c[who][0]);}
    if(rg>mid) {c[who][1]=newnode();fa[c[who][1]]=who;build(mid+1,rg,c[who][1]);}
	update(who);
}
inline void init(){
    root=1,tot=2;
    fa[root]=0,c[root][1]=2,fa[2]=1,c[2][0]=newnode(),fa[c[2][0]]=2;
    build(1,n,c[2][0]);
    update(2),update(1);
}
void dfs(int x){
    pushdown(x);
	if(c[x][0]) dfs(c[x][0]);
    if(w[x]) printf("%d ",w[x]);
    if(c[x][1]) dfs(c[x][1]);
}
int main(){
    n=read(),m=read();
	init();
    while(m--){
      l=read(),r=read();
      l=find(root,l);splay(l,root);
      r=find(root,r+2);splay(r,c[l][1]);
      rev[c[r][0]]^=1;
	}
	dfs(root);
}