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(){;}
只要是活着的东西,就算是神我也杀给你看。