令先手爲$A$,後手爲$B$,將相鄰同色棋子合併成塊,首先特判一些狀況:blog
無視全部大小爲$1$的塊,考慮剩下塊裏相鄰兩塊,它們往外擴張比往內縮更優:遊戲
通過上述轉化後,再也不存在大小爲$1$的塊,當存在大小至少爲$3$且內部存在空隙的自由塊時,該塊顯然能夠永遠操做下去。假設不存在自由塊,那麼顯然不會平局,遊戲等價於每堆石子數爲相鄰兩塊間距的Nim遊戲。string
分如下狀況討論:io
時間複雜度$O(B+C)$。class
#include<cstdio> #include<cstring> #define CLR(x) memset(x,0,sizeof x) const int N=1000010,BUF=12000000; char Buf[BUF],*buf=Buf; int Case,m,n,ce,A,B,i,j,k,o,x,st,a[N],b[N],can10,can11,can01,can00; struct P{ int x;char col; P(){} P(int _x,char _col){x=_x,col=_col;} }q[N]; struct E{ int len,cnt,dis;char col; E(){} E(int _len,int _cnt,int _dis,char _col){len=_len,cnt=_cnt,dis=_dis,col=_col;} bool free(){return len>cnt&&cnt>=3;} }e[N]; int cfree[2],cmove[2],cnt[2],cmay[2],sum[2],CFREE,CMAY0,CMAY1; inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;} inline void cal(){ if(e[0].col==e[ce-1].col){ ce--; e[0].len+=e[ce].len+e[ce].dis; e[0].cnt+=e[ce].cnt; } CLR(cfree),CLR(cmove),CLR(cnt),CLR(cmay);CLR(sum); for(i=0;i<ce;i++){ cnt[e[i].col]++; if(e[i].free())cfree[e[i].col]++,cmove[e[i].col]++,cmay[e[i].col]++; if(e[i].len>e[i].cnt)cmove[e[i].col]++; if(e[i].dis){ cmove[e[i].col]++; if(e[i].cnt>=3){ cmay[e[i].col]++; sum[e[i].col]^=e[i].dis; } } if(e[(i-1+ce)%ce].dis){ cmove[e[i].col]++; if(e[i].cnt>=3){ cmay[e[i].col]++; sum[e[i].col]^=e[(i-1+ce)%ce].dis; } } } } inline bool can_block_b(){ if(cfree[1])return 0; if(cmove[1]>1)return 0; for(i=0;i<ce;i++)if(e[i].col==1&&e[i].len>e[i].cnt)return 0; for(i=0;i<ce;i++)if(e[i].col==1){ if(e[i].dis&&e[(i+1)%ce].len>1)return 1; if(e[(i-1+ce)%ce].dis&&e[(i-1+ce)%ce].len>1)return 1; } return 0; } inline void change(int x,int y){ CFREE=cfree[0],CMAY0=cmay[0],CMAY1=cmay[1]; if(e[x].cnt>=3)CFREE++,CMAY0++; if(e[y].cnt>=3&&!e[y].free())CMAY1--; } inline int solve(){ read(m),read(A),read(B); for(i=1;i<=A;i++)read(a[i]); for(i=1;i<=B;i++)read(b[i]); //Circle is full, so A can't move if(A+B==m)return -1; n=0; i=j=1; while(i<=A&&j<=B)if(a[i]<b[j])q[++n]=P(a[i++],0);else q[++n]=P(b[j++],1); while(i<=A)q[++n]=P(a[i++],0); while(j<=B)q[++n]=P(b[j++],1); ce=0; for(i=1;i<=n;i=j+1){ for(j=i;j<n&&q[i].col==q[j+1].col;j++); e[ce++]=E(q[j].x-q[i].x+1,j-i+1,q[j+1].x-q[j].x-1,q[i].col); } e[ce-1].dis=q[1].x-q[n].x-1+m; cal(); //All blocks' length is 1, draw for(i=0;i<ce;i++)if(e[i].len!=1)break; if(i>=ce)return 0; //A can't move if(!cmove[0])return -1; //A can make B not to move if(can_block_b())return 1; for(i=0;i<ce;i++)if(e[i].len>1){st=i;break;} for(i=0;i<ce;i=j){ for(j=i+1;j<=ce;j++)if(e[(st+j)%ce].len>1)break; int l=(st+i)%ce; if(e[l].col!=e[(st+j)%ce].col)for(k=i+1,o=1;k<j;k++,o^=1){ x=(st+k)%ce; if(o)e[x].dis=0; e[x].len=e[x].cnt=2; }else{ e[l].len+=e[l].dis; e[l].dis=0; for(k=i+1,o=1;k<j;k++,o^=1){ x=(st+k)%ce; if(o)cnt[e[x].col]--; e[l].len+=e[x].len+e[x].dis; e[l].cnt+=e[x].cnt; } } } //No such blocks if(!cnt[0])return -1; if(!cnt[1])return 1; for(i=n=0;i<ce;i++)if(e[i].len>1)e[n++]=e[i]; for(ce=i=1;i<n;i++)if(e[i].col==e[ce-1].col){ e[ce-1].len+=e[i].len+e[ce-1].dis; e[ce-1].cnt+=e[i].cnt; e[ce-1].dis=e[i].dis; }else e[ce++]=e[i]; cal(); //A can't move if(!cmove[0])return -1; //A can make B not to move if(can_block_b())return 1; can10=can11=can01=can00=0; CFREE=cfree[0],CMAY0=cmay[0],CMAY1=cmay[1]; if(CFREE){ if(!CMAY1)can10=1; if(cfree[1])can11=1; } for(x=i=0;i<ce;i++)x^=e[i].dis; for(i=0;i<ce;i++)if(e[i].col==0){ if(e[i].dis){ change(i,(i+1)%ce); if((CMAY0>1||CFREE)&&!CMAY1)can10=1; if(CFREE&&CMAY1)can11=1; if(!CFREE&&CMAY1)can01=1; if(!CMAY1&&x==e[i].dis)can00=1; if(!CFREE&&CMAY0==1&&!CMAY1)if(x^e[i].dis^sum[0])can00=1; } if(e[(i-1+ce)%ce].dis){ change(i,(i-1+ce)%ce); if((CMAY0>1||CFREE)&&!CMAY1)can10=1; if(CFREE&&CMAY1)can11=1; if(!CFREE&&CMAY1)can01=1; if(!CMAY1&&x==e[(i-1+ce)%ce].dis)can00=1; if(!CFREE&&CMAY0==1&&!CMAY1)if(x^e[(i-1+ce)%ce].dis^sum[0])can00=1; } } if(can10)return 1; if(can00)return 1; if(can11)return 0; if(can01)return -1; return x?1:-1; } int main(){ fread(Buf,1,BUF,stdin);read(Case); while(Case--){ int x=solve(); if(x>0)puts("B"); if(!x)puts("R"); if(x<0)puts("C"); } return 0; }