NOI2007项链工厂——sbTreap代码


  1
2 #include <iostream>
3 #include <cstdio>
4 #include <algorithm>
5 #include <cstring>
6 #include <cstdlib>
7
8 using namespace std;
9 struct node
10 {
11 int data;
12 int left;
13 int right;
14 int key;
15 int size;
16 bool turn;
17 int ans;
18 int mark;
19 node* ls,*rs;
20 node(int dat=0,int ke=0)
21 {
22 data=dat;
23 key=ke;
24 left=data;
25 right=data;
26 size=1;
27 turn=false;
28 mark=0;
29 ans=1;
30 ls=NULL;
31 rs=NULL;
32 }
33 }no[500010];
34
35
36 void pushdown(node* now)
37 {
38 if (now->mark)
39 {
40 if (now->ls)
41 {
42 now->ls->data=now->mark;
43 now->ls->mark=now->mark;
44 now->ls->left=now->mark;
45 now->ls->right=now->mark;
46 now->ls->ans=1;
47 }
48 if (now->rs)
49 {
50 now->rs->data=now->mark;
51 now->rs->mark=now->mark;
52 now->rs->left=now->mark;
53 now->rs->right=now->mark;
54 now->rs->ans=1;
55 }
56 now->mark=0;
57 }
58 if (now->turn)
59 {
60 node* l=now->ls;
61 node* r=now->rs;
62 if (now->ls)
63 now->ls->left^=now->ls->right^=now->ls->left^=now->ls->right;
64 if (now->rs)
65 now->rs->left^=now->rs->right^=now->rs->left^=now->rs->right;
66 now->ls=r;
67 now->rs=l;
68 if (now->ls) now->ls->turn=!now->ls->turn;
69 if (now->rs) now->rs->turn=!now->rs->turn;
70 now->turn=false;
71 }
72 }
73
74 void update(node* now)
75 {
76 now->size=1;
77 now->ans=1;
78 now->left=now->data;
79 now->right=now->data;
80 if (now->ls)
81 {
82 now->size+=now->ls->size;
83 now->ans+=now->ls->ans;
84 now->left=now->ls->left;
85 }
86 if (now->rs)
87 {
88 now->size+=now->rs->size;
89 now->ans+=now->rs->ans;
90 now->right=now->rs->right;
91 }
92 if (now->ls)
93 if (now->ls->right==now->data) now->ans--;
94 if (now->rs)
95 if (now->rs->left==now->data) now->ans--;
96 }
97
98 node* merge(node* a,node* b)
99 {
100 if (!b) return a;
101 if (!a) return b;
102 pushdown(a);
103 pushdown(b);
104 if (a->key<=b->key)
105 {
106 a->rs=merge(a->rs,b);
107 update(a);
108 return a;
109 }
110 else
111 {
112 b->ls=merge(a,b->ls);
113 update(b);
114 return b;
115 }
116 }
117
118 struct npair
119 {
120 node* l,*r;
121 npair(node* a,node* b)
122 {
123 l=a;
124 r=b;
125 }
126 };
127
128 npair split(node* a,int k)
129 {
130 if (!a) return npair(NULL,NULL);
131 if (k==0) return npair(NULL,a);
132 pushdown(a);
133 if (a->ls)
134 {
135 if (a->ls->size>=k)
136 {
137 npair km=split(a->ls,k);
138 a->ls=km.r;
139 update(a);
140 return npair(km.l,a);
141 }
142 else
143 {
144 npair km=split(a->rs,k-a->ls->size-1);
145 a->rs=km.l;
146 update(a);
147 return npair(a,km.r);
148 }
149 }
150 else
151 {
152 npair km=split(a->rs,k-1);
153 a->rs=km.l;
154 update(a);
155 return npair(a,km.r);
156 }
157 }
158 node* insert(node* root,node* newnode)
159 {
160 return merge(root,newnode);
161 }
162
163 void turn(node* now)
164 {
165 now->turn=!now->turn;
166 now->left^=now->right^=now->left^=now->right;
167 }
168
169 node* rotate(node* root,int num)
170 {
171 int n=root->size;
172 num=num%n;
173 int k=n-num;
174 npair km = split(root,k);
175 return merge(km.r,km.l);
176 }
177
178 node* flip(node* root)
179 {
180 int n=root->size;
181 int r;
182 if (n%2==1)
183 {
184 r=n/2+1;
185 }
186 else
187 {
188 r=n/2;
189 }
190 npair km=split(root,r);
191 npair km2=split(km.l,1);
192 if (n%2==1)
193 {
194 turn(km2.r);
195 turn(km.r);
196 return merge(merge(km2.l,km.r),km2.r);
197 }
198 else
199 {
200 npair km3=split(km.r,1);
201 turn(km2.r);
202 turn(km3.r);
203 return merge(merge(km2.l,km3.r),merge(km3.l,km2.r));
204 }
205 }
206
207 node* swap(node* root,int i,int j)
208 {
209 if (i>j) i^=j^=i^=j;
210 if (i==j) return root;
211 npair km=split(root,i);
212 npair km2=split(km.l,i-1);
213 npair km3=split(km.r,j-i);
214 npair km4=split(km3.l,j-i-1);
215 return merge(merge(merge(km2.l,km4.r),km4.l),merge(km2.r,km3.r));
216 }
217
218 node* paint(node* root,int i,int j,int x)
219 {
220 int n=root->size;
221 if (i<=j)
222 {
223 npair km=split(root,i-1);
224 npair km2=split(km.r,j-i+1);
225 km2.l->mark=x;
226 km2.l->data=x;
227 km2.l->ans=1;
228 km2.l->left=x;
229 km2.l->right=x;
230 return merge(km.l,merge(km2.l,km2.r));
231 }
232 else
233 {
234 npair km=split(root,j);
235 int nn=km.r->size;
236 npair km2=split(km.r,nn-n+i-1);
237 km.l->mark=x;
238 km.l->data=x;
239 km.l->ans=1;
240 km.l->left=x;
241 km.l->right=x;
242 km2.r->mark=x;
243 km2.r->data=x;
244 km2.r->ans=1;
245 km2.r->left=x;
246 km2.r->right=x;
247 return merge(km.l,merge(km2.l,km2.r));
248 }
249 }
250
251 node* root;
252 int countS(int i,int j)
253 {
254 int n=root->size;
255 if (i<=j)
256 {
257 npair km=split(root,i-1);
258 npair km2=split(km.r,j-i+1);
259 int ret=km2.l->ans;
260 root=merge(km.l,merge(km2.l,km2.r));
261 return ret;
262 }
263 else
264 {
265 npair km=split(root,j);
266 int nn=km.r->size;
267 npair km2=split(km.r,nn-n+i-1);
268 int ret=km.l->ans+km2.r->ans;
269 if (km.l->left==km2.r->right) ret--;
270 root=merge(km.l,merge(km2.l,km2.r));
271 return ret;
272 }
273 }
274
275 int count()
276 {
277 int ret=root->ans;
278 if (root->left==root->right&&ret!=1) ret--;
279 return ret;
280 }
281
282 void print(node* now,bool b)
283 {
284 if (!now) return;
285 b=b^now->turn;
286 // if (!b)
287 print(now->ls,b);
288 // else
289 // print(now->rs,b);
290 printf("data: %d size: %d mark: %d turn: %d ans: %d left: %d right: %d\n",now->data,now->size,now->mark,now->turn,now->ans,now->left,now->right);
291 // if (!b)
292 print(now->rs,b);
293 // else
294 // print(now->ls,b);
295 }
296
297 void print(node* now)
298 {
299 if (!now) return;
300 pushdown(now);
301 print(now->ls);
302 printf("%d\n",now->data);
303 print(now->rs);
304 }
305
306 int cnt=-1;
307 int main()
308 {
309 int n,c;
310 scanf("%d%d",&n,&c);
311 int j;
312 for (int i=1;i<=n;++i)
313 {
314 scanf("%d",&j);
315 node* q=&no[++cnt];
316 *q=node(j,rand());
317 root=insert(root,q);
318 }
319 int m;
320 scanf("%d",&m);
321 char cmd[3];
322 int l,r,k;
323 for (int i=1;i<=m;++i)
324 {
325 scanf("%s",cmd);
326 if (cmd[0]==‘R‘){scanf("%d",&k);root=rotate(root,k);}
327 if (cmd[0]==‘F‘){root=flip(root);}
328 if (cmd[0]==‘S‘){scanf("%d%d",&l,&r);root=swap(root,l,r);}
329 if (cmd[0]==‘P‘){scanf("%d%d%d",&l,&r,&k);root=paint(root,l,r,k);}
330 if (cmd[0]==‘C‘&&cmd[1]!=‘S‘){printf("%d\n",count());}
331 if (cmd[0]==‘C‘&&cmd[1]==‘S‘){scanf("%d%d",&l,&r);printf("%d\n",countS(l,r));}
332 // printf("%d\n",i);
333 // printf("--------------------\n");
334 // print(root,false);
335 // printf("--------------------\n");
336 }
337 return 0;
338 }

NOI2007项链工厂——sbTreap代码

时间: 2024-10-11 06:25:24

NOI2007项链工厂——sbTreap代码的相关文章

bzoj 1493: [NOI2007]项链工厂(线段树)

1493: [NOI2007]项链工厂 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 1256  Solved: 545[Submit][Status][Discuss] Description Input 输 入文件第一行包含两个整数N, c,分别表示项链包含的珠子数目以及颜色 数目.第二行包含N 个整数,x1, x2…, xn,表示从位置1 到位置N 的珠子的颜色, 1 ≤ xi ≤ c.第三行包含一个整数Q,表示命令数目.接下来的Q 行每行一

【BZOJ 1493】[NOI2007]项链工厂

1493: [NOI2007]项链工厂 Time Limit: 30 Sec  Memory Limit: 64 MB Submit: 992  Solved: 454 [Submit][Status] Description   Input 输入文件第一行包含两个整数N, c,分别表示项链包含的珠子数目以及颜色 数目.第二行包含N 个整数,x1, x2-, xn,表示从位置1 到位置N 的珠子的颜色, 1 ≤ xi ≤ c.第三行包含一个整数Q,表示命令数目.接下来的Q 行每行一条命令, 如上

BZOJ1493 [NOI2007]项链工厂

未完待续... 1493: [NOI2007]项链工厂 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 1320  Solved: 576[Submit][Status][Discuss] Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链.该项链自助生产系 统包括硬件系统与软件系统,软件系统与

数据结构(Splay平衡树): [NOI2007] 项链工厂

[NOI2007] 项链工厂 ★★★   输入文件:necklace.in   输出文件:necklace.out   简单对比 时间限制:4 s   内存限制:512 MB [问题描述] T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱.最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链. 该项链自助生产系统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的项链.该

bzoj1493[NOI2007]项链工厂 线段树

1493: [NOI2007]项链工厂 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 1712  Solved: 723[Submit][Status][Discuss] Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链.该项链自助生产系 统包括硬件系统与软件系统,软件系统与用户进行交互并控

BZOJ1493 NOI2007 项链工厂 线段树模拟

提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493 题目大意:给一个数列,进行一系列操作.包括旋转,翻转,改变等操作,以及查询颜色段数. 题目分析:数列中元素的相对位置没有改变,因此不需要用splay去做,而是可以用线段树解决这类问题. 旋转操作直接改变变量rotate,翻转操作用异或即可.每次询问先利用rotate求出当前1号位是谁,这样可以根据翻转标记确定区间.如果区间跨越n,那么合并的时候要考虑左边一段的右端和右边一段的左端.

1493: [NOI2007]项链工厂

线段树. 真还就是个线段树.. 除去操作1,2的话,线段树很容易就处理了,问题在于如何处理操作1和2.(这点没想到).. 我们用一个delta维护操作1,如果没有旋转就+k,不然就-k. 每次读入i和j的时候用trans处理一下,就成功在O(1)的时间解决了操作1和2. 细节很重要. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 2

BZOJ 1493 NOI2007 项链工厂

题目大意:维护一个环,每个点有一个颜色,提供6种操作: 1.将这个环顺时针旋转k 2.沿点1所在直径翻转 3.将两个珠子互换 4.将一段区间染色 5.查询这个环上有多少颜色段 6.查询一段区间有多少颜色段 关于颜色段通用的处理方法是每个区间记录三个值,颜色段数.左端点颜色.右端点颜色,合并时颜色段数相加,如果左区间右端点和右区间左端点颜色相同则减一 然后用Splay维护区间即可 不过这题还是有一些小细节需要处理 首先null节点要保证不会被修改 然后更新的时候特判 如果一段区间颜色是0直接返回另

【BZOJ-1493】项链工厂 Splay

1493: [NOI2007]项链工厂 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 1440  Solved: 626[Submit][Status][Discuss] Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链.该项链自助生产系统包括硬件系统与软件系统,软件系统与用户进行交互并控制