BZOJ 3223 文艺平衡树

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

splay区间操作大裸题不解释。

  1 #include<queue>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 using namespace std;
  5 
  6 #define maxn 100010
  7 const int inf = 1 << 30;
  8 queue <int> team;
  9 struct TREE
 10 {
 11     int ch[maxn][2],fa[maxn],cnt,root;
 12     int key[maxn],size[maxn],t[maxn];
 13     
 14     inline int newnode()
 15     {
 16         if (team.empty()) return ++cnt;
 17         int ret = team.front(); team.pop();
 18         return ret;
 19     }
 20 
 21     inline TREE()
 22     {
 23         root = newnode();
 24         key[root] = -inf; ++t[root];
 25         updata(root);
 26         add(inf);
 27     }
 28 
 29     inline int find(int rank,int have,int now)
 30     {
 31         if (have+size[ch[now][0]]<rank&&have+size[ch[now][0]]+t[now]>=rank) return now;
 32         if (have+size[ch[now][0]]+t[now]<rank) return find(rank,have+size[ch[now][0]]+t[now],ch[now][1]);
 33         else return find(rank,have,ch[now][0]);
 34     }
 35     
 36     inline void updata(int now) { size[now] = size[ch[now][0]] + size[ch[now][1]] + t[now]; }
 37 
 38     inline void rotate(int x)
 39     {
 40         int y = fa[x],z = fa[y],l = ch[y][0] != x,r = l ^ 1;
 41         if (z != 0) ch[z][ch[z][0] != y] = x;
 42         fa[x] = z; fa[y] = x; fa[ch[x][r]] = y;
 43         ch[y][l] = ch[x][r]; ch[x][r] = y;
 44         updata(y); updata(x);
 45     }
 46     
 47     inline void splay(int x,int aim)
 48     {
 49         int p = fa[aim];
 50         while (fa[x] != p)
 51         {
 52             int y = fa[x],z = fa[y];
 53             if (z != p)
 54             {
 55                 if ((ch[z][0] == y)^(ch[y][0] == x)) rotate(x);
 56                 else rotate(y);
 57             }
 58             rotate(x);
 59         }
 60         if (aim == root) root = x;
 61     }
 62 
 63     inline int search(int x)
 64     {
 65         int now = root;
 66         while (now)
 67         {
 68             if (key[now] == x) break;
 69             now = ch[now][x > key[now]];
 70         }
 71         return now;
 72     }
 73 
 74     inline void add(int x)
 75     {
 76         int now = root,pre = 0;
 77         while (now)
 78         {
 79             pre = now;
 80             now = ch[now][x > key[now]];
 81         }
 82         now = newnode();
 83         fa[now] = pre; ch[pre][x > key[pre]] = now;
 84         key[now] = x; ++t[now];
 85         pre = now;
 86         while (now)
 87         {
 88             updata(now);
 89             now = fa[now];
 90         }
 91         splay(pre,root);
 92     }
 93 
 94     inline int qrank(int x)
 95     {
 96         int now = root,ret = 0;
 97         while (key[now] != x)
 98         {
 99             if (x < key[now]) now = ch[now][0];
100             else ret += size[ch[now][0]] + t[now],now = ch[now][1];
101         }
102         return ret + size[ch[now][0]] + 1;
103     }
104     
105     inline void insert(int x)
106     {
107         int p = search(x);
108         if (p)
109         {
110             splay(p,root);
111             ++t[p];
112             updata(p);
113         }
114         else add(x);
115     }
116 
117     inline void del(int x)
118     {
119         int now = search(x),k = qrank(x);
120         int p = find(k-1,0,root),q = find(k + t[now],0,root);
121         splay(p,root);
122         splay(q,ch[p][1]);
123         if (--t[now])
124         {
125             updata(now);
126             updata(q);
127             updata(p);
128         }
129         else
130         {
131             ch[q][0] = 0; fa[now] = 0;
132             updata(q);
133             updata(p);
134             team.push(now);
135         }
136     }
137 
138     inline int ask(int x,int sign)
139     {
140         int now = root,ret;
141         while (now)
142         {
143             if (sign)
144             {
145                 if (key[now] > x)
146                     ret = now,now = ch[now][0];
147                 else now = ch[now][1];
148             }
149             else
150             {
151                 if (key[now] < x)
152                     ret = now,now = ch[now][1];
153                 else now = ch[now][0];
154             }
155         }
156         return key[ret];
157     }
158 }tree;
159 
160 inline int read()
161 {
162     int x=0,f=1;char ch=getchar();
163     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
164     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
165     return x*f;
166 }
167 
168 int main()
169 {
170     freopen("3224.in","r",stdin);
171     freopen("3224.out","w",stdout);
172     int T = read();
173     while (T--)
174     {
175         int opt = read();
176         if (opt == 1) tree.insert(read());
177         else if (opt == 2) tree.del(read());
178         else if (opt == 3) printf("%d\n",tree.qrank(read())-1);
179         else if (opt == 4) printf("%d\n",tree.key[tree.find(read()+1,0,tree.root)]);
180         else if (opt == 5) printf("%d\n",tree.ask(read(),0));
181         else printf("%d\n",tree.ask(read(),1));
182     }
183     fclose(stdin); fclose(stdout);
184     return 0;
185 }
View Code

 

高考结束,重新回归。
posted @ 2015-02-16 19:55  lmxyy  阅读(139)  评论(0编辑  收藏  举报