【Splay】bzoj3223-Tyvj1729文藝平衡樹

1、題目

Description

您須要寫一種數據結構(可參考題目標題),來維護一個有序數列,其中須要提供如下操做:翻轉一個區間,例如原有序序列是5 4 3 2 1,翻轉區間是[2,4]的話,結果是5 2 3 4 1 php

Input

第一行爲n,m n表示初始序列有n個數,這個序列依次是(1,2……n-1,n)  m表示翻轉操做次數
接下來m行每行兩個數[l,r] 數據保證 1<=l<=r<=n  html

Output

輸出一行n個數字,表示原始序列通過m次變換後的結果 node

Sample Input

5 3c++

1 3數據結構

1 3ide

1 4spa

Sample Output

4 3 2 1 5code

HINT

N,M<=100000htm

順便附上原題連接→_→Problem 3223. -- Tyvj 1729 文藝平衡樹blog

2、代碼實現

裸Splay,基本操做都不齊_(:з」∠)_不過這題有個特色,就是關鍵字和原序列序號是同樣的,因此能夠少開一個變量(雖然這並無什麼卵用┑( ̄Д  ̄)┍

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=1e5+10;
 4 int n,m;
 5 struct node
 6 {
 7     int siz,fa,c[2];
 8     bool rev;//翻轉標記
 9 }tr[MAXN];
10 int root;
11 void push_up(int k)
12 {
13     tr[k].siz=tr[tr[k].c[0]].siz+tr[tr[k].c[1]].siz+1;
14     return;
15 }
16 void push_down(int k)
17 {
18     if(tr[k].rev)
19     {
20         swap(tr[k].c[0],tr[k].c[1]);
21         tr[k].rev=0;
22         tr[tr[k].c[0]].rev^=1,tr[tr[k].c[1]].rev^=1;
23     }
24     return;
25 }
26 void rotate(int &k,int x)
27 {
28     int y=tr[x].fa,z=tr[y].fa;
29     bool dy=tr[y].c[1]==x,dz=tr[z].c[1]==y;
30     push_down(y);
31     if(k==y)k=x,tr[x].fa=z;
32     else tr[z].c[dz]=x,tr[x].fa=z;
33     tr[y].c[dy]=tr[x].c[dy^1],tr[tr[x].c[dy^1]].fa=y;
34     tr[x].c[dy^1]=y,tr[y].fa=x;
35     push_up(y);
36     return;
37 }
38 void splay(int &k,int x)
39 {
40     push_down(x);
41     while(k!=x)
42     {
43         int y=tr[x].fa,z=tr[y].fa;
44         if(k!=y)
45         {
46             if(tr[y].c[1]==x^tr[z].c[1]==y)rotate(k,x);
47             else rotate(k,y);
48         }
49         rotate(k,x);
50     }
51     push_up(x);
52     return;
53 }
54 int find(int k,int x)
55 {
56     if(!k)return 0;
57     push_down(k);
58     if(x<=tr[tr[k].c[0]].siz)return find(tr[k].c[0],x);
59     if(x==tr[tr[k].c[0]].siz+1)return k;
60     return find(tr[k].c[1],x-tr[tr[k].c[0]].siz-1);
61 }
62 void print(int k)
63 {
64     if(!k)return;
65     push_down(k);
66     print(tr[k].c[0]);
67     if(k>1&&k<n+2)printf("%d ",k-1);
68     print(tr[k].c[1]);
69 }
70 int main()
71 {
72     scanf("%d%d",&n,&m);
73     for(int i=1;i<=n+2;++i)
74     {
75         tr[i].siz=n+3-i;
76         tr[i].fa=i-1,tr[i].c[1]=i+1;
77     }
78     tr[n+2].c[1]=0,root=1;
79     while(m--)
80     {
81         int l,r;
82         scanf("%d%d",&l,&r);
83         splay(root,find(root,l));
84         splay(tr[root].c[1],find(root,r+2));
85         tr[tr[tr[root].c[1]].c[0]].rev^=1;
86     }
87     print(root);
88     printf("\n");
89     return 0;
90 }
bzoj3223-文藝平衡樹

弱弱地說一句,本蒟蒻碼字也不容易,轉載請註明出處http://www.cnblogs.com/Maki-Nishikino/p/6247021.html

相關文章
相關標籤/搜索