#include <bits/stdc++.h>
using namespace std;
int coltag[1919810<<2],a[1919810],n,c,len[1919810<<2],q,hd=1,dir=1;
struct SegTree{
int prt,lcol,rcol;
SegTree(int prt=0,int lcol=0,int rcol=0):
prt(prt),lcol(lcol),rcol(rcol){}
}t[1919810<<2];
SegTree pushup(SegTree lson,SegTree rson){
return SegTree(((lson.rcol==rson.lcol&&lson.rcol)?lson.prt+rson.prt-1:lson.prt+rson.prt),lson.lcol,rson.rcol);
}
inline void tag(int x,int col){
coltag[x]=col;
t[x]=SegTree(1,col,col);
}
void pushdown(int x){
if(coltag[x]){
tag(x<<1,coltag[x]);
tag(x<<1|1,coltag[x]);
coltag[x]=0;
}
}
void build(int x,int l,int r){
len[x]=r-l+1;
if(l==r){
t[x]=SegTree(1,a[l],a[l]);
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
t[x]=pushup(t[x<<1],t[x<<1|1]);
}
int findcol(int x,int l,int r,int pos){
if(l==r&&l==pos) return t[x].lcol;
pushdown(x);
int mid=(l+r)>>1;
if(mid>=pos) return findcol(x<<1,l,mid,pos);
else return findcol(x<<1|1,mid+1,r,pos);
}
void flatten(int x,int l,int r,int L,int R,int col){
if(L<=l&&r<=R){
tag(x,col);
return;
}
pushdown(x);
int mid=(l+r)>>1;
if(L<=mid) flatten(x<<1,l,mid,L,R,col);
if(R>mid) flatten(x<<1|1,mid+1,r,L,R,col);
t[x]=pushup(t[x<<1],t[x<<1|1]);
}
SegTree query(int x,int l,int r,int L,int R){
if(L<=l&&r<=R){
return t[x];
}
pushdown(x);
SegTree r1,r2,res;
r1=r2=SegTree();
int mid=(l+r)>>1;
if(L<=mid) r1=query(x<<1,l,mid,L,R);
if(R>mid) r2=query(x<<1|1,mid+1,r,L,R);
res=pushup(r1,r2);
return res;
}
int main(){
scanf("%d%d",&n,&c);
for(int i=1;i<=n;++i){
scanf("%d",a+i);
a[i+n]=a[i];
}
int N=2*n;
build(1,1,N);
scanf("%d",&q);
while(q--){
string opt;
int i,j,x;
cin>>opt;
if(opt[0]=='R'){
scanf("%d",&i);
hd=((hd-1-dir*i)%n+n)%n+1;
}
else if(opt[0]=='F'){
dir=-dir;
}
else if(opt=="C"){
SegTree ans=query(1,1,N,1,N);
printf("%d\n",ans.prt/2);
}
else{
bool flag=false;
int _i,_j;
scanf("%d%d",&i,&j);
i=((hd-1+dir*(i-1))%n+n)%n+1;
j=((hd-1+dir*(j-1))%n+n)%n+1;
if(i>j){
flag=true;
_j=j;
j+=n;
_i=i+n;
}
else{
_j=j+n;
_i=i+n;
}
if(opt[0]=='S'){
int coli=findcol(1,1,N,i),colj=findcol(1,1,N,j);
flatten(1,1,N,i,i,colj);
flatten(1,1,N,_i,_i,colj);
flatten(1,1,N,j,j,coli);
flatten(1,1,N,_j,_j,coli);
}
else if(opt[0]=='P'){
scanf("%d",&x);
flatten(1,1,N,i,j,x);
if(flag){
flatten(1,1,N,1,_j,x);
flatten(1,1,N,_i,N,x);
}
else flatten(1,1,N,_i,_j,x);
}
else{
SegTree ans=query(1,1,N,i,j);
printf("%d\n",ans.prt);
}
}
}
return 0;
}
思路:dir表示方向,hd表示顶点,用2n的数组存环,则环的总份数为2n数组的部份数/2,处理i,j使i<j且在数组上代表相同点的地方做等价操作,写法参考P2572最上方的题解。