#include #include const int BLOCKSIZE = 800; const int MAXL = 500000+10; const int MAXBLOCK = MAXL/BLOCKSIZE*2+100; inline void swap(int &a,int &b){a^=b;b^=a;a^=b;} inline int min(int a,int b){return a0; --i)if(str[i]!=str[i-1])++account[b]; side[b][0]=str[0]; side[b][1]=str[count[b]-1]; } } void maintainlist(int b){ for(; b!=-1; b=next[b]) for(int t=next[b]; t!=-1 && count[b]+count[t]<=BLOCKSIZE; t=next[b]){ if( !(same[b] && same[t] && samevalue[b]==samevalue[t]) ){ reverseblock(b); reverseblock(t); if(same[b])for(int i=count[b]-1; i>=0; --i)data[b][i]=samevalue[b]; same[b]=false; int cb=count[b],*str=data[b]; if(same[t])for(int i=count[t]-1,sv=samevalue[t];i>=0;--i)str[cb+i]=sv; else for(int i=count[t]-1,*a=data[t];i>=0;--i)str[cb+i]=a[i]; } count[b]+=count[t]; next[b]=next[t]; delnode(t); maintainblock(b); } } void find(int &p,int &b){ for(b=0; b!=-1 && p>count[b]; b=next[b]) p-=count[b]; } void fillblock(int b,int n,int str[],int e){ next[b]=e; count[b]=n; memcpy(data[b], str, n*sizeof(int)); same[b]=reversed[b]=false; maintainblock(b); } void fillblock(int b,int n,int v,int e){ next[b]=e; count[b]=n; same[b]=true; samevalue[b]=v; reversed[b]=false; maintainblock(b); } void splite(int b,int p){ if(b==-1 || count[b]==p)return; int t=newnode(); reverseblock(b); if(same[b]) fillblock(t, count[b]-p, samevalue[b], next[b]); else fillblock(t, count[b]-p, data[b]+p, next[b]); count[b]=p; next[b]=t; maintainblock(b); } void insert(int p,int n,int str[]){ int b,t,i; find(p,b); splite(b,p); for(i=0; i + BLOCKSIZE <= n; i+=BLOCKSIZE){ t=newnode(); fillblock(t, BLOCKSIZE, str+i, next[b]); next[b]=t; b=t; } if(n-i){ t=newnode(); fillblock(t, n-i, str+i, next[b]); next[b]=t; } maintainlist(b); } int list[MAXBLOCK]; void reverse(int p,int n){ int b,i,t; find(p,b); splite(b,p); for(i=0,t=next[b]; n>count[t]; n-=count[t],++i,t=next[t]) list[i]=t; if(n && t!=-1){ splite(t,n); list[i++]=t; t=next[t]; } next[b]=list[--i]; for(; i>=0; --i){ next[list[i]] = i ? list[i-1] : t; reversed[list[i]] = ! reversed[list[i]]; } maintainlist(b); } void makesame(int p,int n,int v){ int b,t; find(p,b); splite(b,p); for(t=next[b]; t!=-1 && n>count[t];n-=count[t], t=next[t]) fillblock(t, count[t], v, next[t]); if(n && t!=-1){ splite(t,n); fillblock(t, n, v, next[t]); } maintainlist(b); } void listswap(int i,int j){ if(i==j)return; int bb,be,s1,s2; find(i,bb); while(count[bb]==i){bb=next[bb];i=0;} s1=same[bb] ? samevalue[bb] : reversed[bb] ? data[bb][count[bb]-i-1] : data[bb][i]; find(j,be); while(count[be]==j){be=next[be];j=0;} s2=same[be] ? samevalue[be] : reversed[be] ? data[be][count[be]-j-1] : data[be][j]; if(s1==s2)return; swap(s1,s2); if(same[bb]){for(int i=count[bb]-1; i>=0; --i)data[bb][i]=samevalue[bb];reversed[bb]=false;} if(same[be]){for(int i=count[be]-1; i>=0; --i)data[be][i]=samevalue[be];reversed[be]=false;} same[bb]=same[be]=false; (reversed[bb] ? data[bb][count[bb]-i-1] : data[bb][i]) = s1; (reversed[be] ? data[be][count[be]-j-1] : data[be][j]) = s2; maintainblock(bb); maintainblock(be); } int countsegment(int p,int n){ if(n<=1)return n; int b; find(p,b); while(p==count[b]){b=next[b];p=0;} int res=1,i,t,l,r,*str=data[b]; --n; if(!same[b]){ if(reversed[b]){for(i=count[b]-p-1; i>0 && n>0; --i,--n)if(str[i]!=str[i-1])++res;} else{for(i=p+1; n>0 && icount[next[t]]; t=next[t]){ n -= count[next[t]]; res += account[next[t]]; if(side[t][!reversed[t]] == side[next[t]][reversed[next[t]]])--res; } if(n>0){--n;res+=(side[t][!reversed[t]]!=side[next[t]][reversed[next[t]]]);} t=next[t];str=data[t]; if(!same[t]){ if(reversed[t]){for(i=count[t]-2; i>=0 && n>0; --i,--n)if(str[i]!=str[i+1])++res;} else{for(i=1; n>0 && i=i)makesame(i-1, j-i+1, x); else{ makesame(0, j, x); makesame(i-1, n-i+1, x); } break; case 'C': if(order[1]=='S'){ scanf("%d%d",&i,&j); if(j>=i)printf("%d\n",countsegment(i-1, j-i+1)); else{ int res=countsegment(i-1, n-i+1); res+=countsegment(0,j); if(same_head_tail())--res; printf("%d\n",res); } }else printf("%d\n",countcircle()); } } fclose(stdin); fclose(stdout); } int main(){ init(); solve(); }