bzoj3223: Tyvj 1729 文藝平衡樹
阿新 • • 發佈:2018-03-15
shu n-1 out bzoj etc pre 表示 cst div
1 3
1 3
1 4
3223: Tyvj 1729 文藝平衡樹
Time Limit: 10 Sec Memory Limit: 128 MBDescription
您需要寫一種數據結構(可參考題目標題),來維護一個有序數列,其中需要提供以下操作:翻轉一個區間,例如原有序序列是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 31 3
1 3
1 4
Sample Output
4 3 2 1 5HINT
N,M<=100000
Source
Splay區間旋轉操作的練手題。
見代碼:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define MAXN 200008 6 using namespace std; 7 8 int n,m,fa[MAXN],tr[MAXN][2],rt,size[MAXN],sz,flag[MAXN]; 9 10 inline int read(){ 11 char ch=getchar(); 12 int x=0,f=1; 13 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) f=-1; ch=getchar();} 14 while(ch>=‘0‘&&ch<=‘9‘) x=(x<<1)+(x<<3)+ch-‘0‘,ch=getchar(); 15 return x*f; 16 } 17 18void pushup(int k){ 19 int l=tr[k][0],r=tr[k][1]; 20 size[k]=size[l]+size[r]+1; 21 } 22 23 void pushdown(int k){ 24 int l=tr[k][0],r=tr[k][1]; 25 if(flag[k]){ 26 swap(tr[k][0],tr[k][1]); 27 flag[l]^=1; flag[r]^=1; 28 flag[k]=0; 29 } 30 } 31 32 void rotate(int x,int &k){ 33 int l,r,y=fa[x],z=fa[y]; 34 if(y==k) k=x; 35 else{ 36 if(tr[z][0]==y) tr[z][0]=x; else tr[z][1]=x; 37 } 38 if(tr[y][0]==x) l=0; else l=1; 39 r=l^1; 40 fa[x]=z; fa[y]=x; fa[tr[x][r]]=y; 41 tr[y][l]=tr[x][r]; tr[x][r]=y; 42 pushup(y); pushup(x); 43 } 44 45 void splay(int x,int &k){ 46 int y,z; 47 while(x!=k){ 48 y=fa[x]; z=fa[y]; 49 if(y!=k){ 50 if(tr[y][0]==x^tr[z][0]==y) rotate(x,k); 51 else rotate(y,k); 52 } 53 rotate(x,k); 54 } 55 } 56 57 void build(int l,int r,int f){ 58 if(l>r) return; 59 int now=l,last=f; 60 if(l==r){ 61 fa[now]=last; size[now]=1; 62 if(l<f) tr[last][0]=l; 63 else tr[last][1]=l; 64 return; 65 } 66 int mid=(l+r)>>1; now=mid; 67 build(l,mid-1,mid); build(mid+1,r,mid); 68 fa[now]=last; pushup(mid); 69 if(mid<f) tr[last][0]=now; 70 else tr[last][1]=now; 71 } 72 73 int find(int k,int x){ 74 pushdown(k); 75 int t1=tr[k][0],t2=tr[k][1]; 76 if(size[t1]+1==x) return k; 77 if(size[t1]>=x) return find(t1,x); 78 return find(t2,x-size[t1]-1); 79 } 80 81 void rever(int l,int r){ 82 int t1=find(rt,l),t2=find(rt,r+2); 83 splay(t1,rt); splay(t2,tr[t1][1]); 84 int k=tr[t2][0]; 85 flag[k]^=1; 86 } 87 88 int main(){ 89 n=read(); m=read(); 90 build(1,n+2,0); rt=(n+3)>>1; 91 for(int i=1;i<=m;i++){ 92 int x,y; 93 x=read(); y=read(); 94 rever(x,y); 95 } 96 for(int i=1;i<=n;i++){ 97 printf("%d ",find(rt,i+1)-1); 98 } 99 } 100
bzoj3223: Tyvj 1729 文藝平衡樹