cogs17 项链工厂 splay

链接:http://cogs.pro/cogs/problem/problem.php?pid=17

题意:写数据结构,支持操作:数颜色段数、修改颜色、转圈、翻转。

操作倒是没什么难的,但本题有两大坑点:从头查到尾不同于查一圈;它只沿一个方向前进,因此可能$x>y$。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 struct node
  7 {
  8     int cnt,lcol,rcol;
  9     node(int x)
 10     {
 11         cnt=1;
 12         if(!x)cnt--;
 13         lcol=rcol=x;
 14     }
 15 };
 16 node operator +(const node a,const node b)
 17 {
 18     node c(0);
 19     c.lcol=a.lcol?a.lcol:b.lcol;c.rcol=b.rcol?b.rcol:a.rcol;
 20     c.cnt=a.cnt+b.cnt-(a.rcol==b.lcol);
 21     return c;
 22 }
 23 struct Splay
 24 {
 25     int num,size;
 26     Splay *ch[2],*pa;
 27     node *s;
 28     int flip,change;
 29     Splay(int x);
 30     void pushup();
 31     void pushdown();
 32 }*null=new Splay(0),*root=null;
 33 Splay::Splay(int x)
 34 {
 35     num=x,size=1;
 36     if(!x)size--;
 37     pa=ch[0]=ch[1]=null;
 38     flip=change=0;
 39     s=new node(x);
 40 }
 41 void Splay::pushup()
 42 {
 43     size=ch[0]->size+ch[1]->size+1;
 44     *s=(*ch[0]->s)+node(num)+(*ch[1]->s);
 45 }
 46 void Splay::pushdown()
 47 {
 48     if(flip)
 49     {
 50         ch[0]->flip^=1;ch[1]->flip^=1;
 51         swap(ch[0]->ch[0],ch[0]->ch[1]);
 52         swap(ch[1]->ch[0],ch[1]->ch[1]);
 53         swap(ch[0]->s->lcol,ch[0]->s->rcol);
 54         swap(ch[1]->s->lcol,ch[1]->s->rcol);
 55         flip=0;
 56     }
 57     if(change)
 58     {
 59         if(ch[0]!=null)
 60         {
 61             ch[0]->num=ch[0]->change=change;
 62             *ch[0]->s=node(change);
 63         }
 64         if(ch[1]!=null)
 65         {
 66             ch[1]->num=ch[1]->change=change;
 67             *ch[1]->s=node(change);
 68         }
 69         change=0;
 70     }
 71 }
 72 void zig(Splay *x)
 73 {
 74     Splay *y=x->pa;
 75     y->pushdown(),x->pushdown();
 76     y->ch[0]=x->ch[1];x->ch[1]->pa=y;
 77     x->ch[1]=y;x->pa=y->pa;
 78     if(y->pa->ch[0]==y)y->pa->ch[0]=x;
 79     else if(y==y->pa->ch[1])y->pa->ch[1]=x;
 80     y->pa=x;
 81     y->pushup();x->pushup();
 82     if(y==root)root=x;
 83 }
 84 void zag(Splay *x)
 85 {
 86     Splay *y=x->pa;
 87     y->pushdown(),x->pushdown();
 88     y->ch[1]=x->ch[0];x->ch[0]->pa=y;
 89     x->ch[0]=y;x->pa=y->pa;
 90     if(y->pa->ch[0]==y)y->pa->ch[0]=x;
 91     else if(y==y->pa->ch[1])y->pa->ch[1]=x;
 92     y->pa=x;
 93     y->pushup();x->pushup();
 94     if(y==root)root=x;
 95 }
 96 void splay(Splay *x,Splay *f)
 97 {
 98     while(1)
 99     {
100         Splay *y=x->pa,*z=y->pa;
101         if(y==f)break;
102         if(z==f)
103         {
104             if(x==y->ch[0])zig(x);
105             else zag(x);
106             break;
107         }
108         if(y->ch[0]==x)
109         {
110             if(z->ch[0]==y)zig(y);
111             zig(x);
112         }
113         else
114         {
115             if(z->ch[1]==y)zag(y);
116             zag(x);
117         }
118     }
119     x->pushup();
120 }
121 void find(Splay *x,int y,Splay *z)
122 {
123     while(1)
124     {
125         x->pushdown();
126         if(y<=x->ch[0]->size)x=x->ch[0];
127         else
128         {
129             y-=x->ch[0]->size;
130             if(y==1)break;
131             y--;
132             x=x->ch[1];
133         }
134     }
135     splay(x,z);
136 }
137 void insert(Splay* &x,int y,Splay *z)
138 {
139     if(x==null)
140     {
141         x=new Splay(y);
142         x->pa=z;
143         splay(x,null);
144         return;
145     }
146     x->pushdown();insert(x->ch[1],y,x);
147 }
148 int n,m,c;
149 char s[10];
150 int haha()
151 {
152     freopen("necklace.in","r",stdin);
153     freopen("necklace.out","w",stdout);
154     scanf("%d%d",&n,&c);
155     insert(root,20010117,null);
156     for(int i=1;i<=n;i++)
157     {
158         int x;
159         scanf("%d",&x);
160         insert(root,x,null);
161     }
162     insert(root,20010117,null);
163     scanf("%d",&m);
164     for(int i=1;i<=m;i++)
165     {
166         scanf("%s",s);
167         int x,y,z;Splay *tmp;
168         switch(s[0])
169         {
170             case 'R':scanf("%d",&x);
171                     find(root,n-x+1,null);find(root,n+2,root);
172                     tmp=root->ch[1]->ch[0];
173                     root->ch[1]->ch[0]=null;
174                     root->ch[1]->pushup();root->pushup();
175                     find(root,1,null);find(root,2,root);
176                     root->ch[1]->ch[0]=tmp;
177                     tmp->pa=root->ch[1];
178                     root->ch[1]->pushup();root->pushup();break;
179             case 'F':find(root,2,null);find(root,n+2,root);
180                     tmp=root->ch[1]->ch[0];
181                     tmp->flip^=1;
182                     swap(tmp->ch[0],tmp->ch[1]);swap(tmp->s->lcol,tmp->s->rcol);break;
183             case 'S':scanf("%d%d",&x,&y);
184                     if(x==y)continue;
185                     if(x>y)swap(x,y);
186                     find(root,x+1,null);find(root,y+1,root);
187                     swap(root->ch[1]->num,root->num);
188                     root->ch[1]->pushup();root->pushup();break;
189             case 'P':scanf("%d%d%d",&x,&y,&z);
190                     if(x<=y)
191                     {
192                         find(root,x,null);find(root,y+2,root);
193                         tmp=root->ch[1]->ch[0];
194                         tmp->num=tmp->change=z;
195                         *tmp->s=node(z);
196                     }
197                     else
198                     {
199                         find(root,x,null);find(root,n+2,root);
200                         tmp=root->ch[1]->ch[0];
201                         tmp->num=tmp->change=z;
202                         *tmp->s=node(z);
203                         find(root,1,null);find(root,y+2,root);
204                         tmp=root->ch[1]->ch[0];
205                         tmp->num=tmp->change=z;
206                         *tmp->s=node(z);
207                     }
208                     break;
209             case 'C':if(!s[1])
210                     {
211                         find(root,1,null);find(root,n+2,root);
212                         tmp=root->ch[1]->ch[0];
213                         int z=tmp->s->cnt-(tmp->s->lcol==tmp->s->rcol);
214                         if(!z)z++;
215                         printf("%d\n",z);break;
216                     }
217                     else
218                     {
219                         scanf("%d%d",&x,&y);
220                         if(x<=y)
221                         {
222                             find(root,x,null);find(root,y+2,root);
223                             tmp=root->ch[1]->ch[0];
224                             printf("%d\n",tmp->s->cnt);
225                         }
226                         else
227                         {
228                             find(root,x,null);find(root,n+2,root);
229                             tmp=root->ch[1]->ch[0];
230                             node temp=*tmp->s;
231                             find(root,1,null);find(root,y+2,root);
232                             tmp=root->ch[1]->ch[0];
233                             temp=temp+*tmp->s;
234                             printf("%d\n",temp.cnt);
235                         }
236                         break;
237                     }
238         }
239     }
240 }
241 int sb=haha();
242 int main(){;}
cogs17

 

posted @ 2017-08-03 21:35  ccc000111  阅读(124)  评论(0编辑  收藏  举报