久违的写一发博客,真是调了好久。
显然F和R操作可以记录两个rev和mov值来忽略掉,剩下就是线段树基本操作了,主要是CS操作不懂它什么意思弄了好久- -
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define N 500005
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
int rev,mov,aa[N],n,Q,k,x,y,l,r,m;
char s[10];
struct Node{
int lval,rval,ans,lz;
Node *ls,*rs;
Node(){lz=0;}
void pushdown(int lf,int rg){
if(lz!=0){
int mid=(lf+rg)>>1;
ls->lz=rs->lz=lz;
ls->lval=ls->rval=rs->lval=rs->rval=lz;
ls->ans=1;
rs->ans=1;
lz=0;
}
}
void update(){
lval=ls->lval;
rval=rs->rval;
ans=ls->ans+rs->ans;
if(ls->rval==rs->lval)ans--;
}
};
Node pool[N*4],*tail=pool,*root;
Node *build(int lf,int rg){
Node *nd=++tail;
if(lf==rg){
nd->lval=nd->rval=aa[lf];
nd->ans=1;
}
else{
int mid=(lf+rg)>>1;
nd->ls=build(lf,mid);
nd->rs=build(mid+1,rg);
nd->update();
}
return nd;
}
void modify(Node *nd,int lf,int rg,int L,int R,int val){
if(L<=lf&&rg<=R){
nd->ans=1;
nd->lval=nd->rval=val;
if(lf!=rg)
nd->lz=val;
return;
}
nd->pushdown(lf,rg);
int mid=(lf+rg)>>1;
if(L<=mid)
modify(nd->ls,lf,mid,L,R,val);
if(R>mid)
modify(nd->rs,mid+1,rg,L,R,val);
nd->update();
}
int get(int x){
int a=x;
if (rev) a=n-a+2;
a-=mov;
for (;a>n;a-=n);
for (;a<1;a+=n);
return a;
}
int query(Node *nd,int lf,int rg,int pos){
if(lf==rg)
return nd->lval;
int mid=(lf+rg)>>1;
nd->pushdown(lf,rg);
if(pos<=mid)
return query(nd->ls,lf,mid,pos);
else
return query(nd->rs,mid+1,rg,pos);
}
int query(Node *nd,int lf,int rg,int L,int R){
if(L<=lf&&rg<=R)
return nd->ans;
int mid=(lf+rg)>>1,ans=0,flag=-1;
nd->pushdown(lf,rg);
if(L<=mid)
ans+=query(nd->ls,lf,mid,L,R),flag=nd->ls->rval;
if(R>mid){
ans+=query(nd->rs,mid+1,rg,L,R);
if(flag==nd->rs->lval)ans--;
}
if(ans<=0)ans=1;
nd->update();
return ans;
}
int main(){
scanf("%d%d",&n,&m);
rep(i,1,n)
scanf("%d",&aa[i]);
root=build(1,n);
scanf("%d",&Q);
while(Q--){
scanf("%s",s);
if(s[0]=='R'){
scanf("%d",&k);
if(rev) mov-=k;else mov+=k;
for (;mov>n;mov-=n);
for (;mov<0;mov+=n);
}
if(s[0]=='F')
rev^=1;
if(s[0]=='S'){
scanf("%d%d",&x,&y);
l=get(x);r=get(y);
int v1=query(root,1,n,l),v2=query(root,1,n,r);
modify(root,1,n,l,l,v2);
modify(root,1,n,r,r,v1);
}
if(s[0]=='P'){
scanf("%d%d%d",&x,&y,&k);
l=get(x);r=get(y);
if(rev)swap(l,r);
if(l<=r)modify(root,1,n,l,r,k);
else{
modify(root,1,n,l,n,k);
modify(root,1,n,1,r,k);
}
}
if(s[0]=='C'&&s[1]!='S'){
int ans=root->ans;
if(root->lval==root->rval&&ans>1)ans--;
printf("%d\n",ans);
}
if(s[0]=='C'&&s[1]=='S'){
scanf("%d%d",&x,&y);
l=get(x);r=get(y);
if(rev)swap(l,r);
int ans;
if(l<=r){
ans=query(root,1,n,l,r);
if (l==1&&r==n&&ans>1&&root->lval==root->rval) ans--;
}
else{
ans=query(root,1,n,l,n)+query(root,1,n,1,r);
if (root->lval==root->rval) ans--;
}
printf("%d\n",ans);
}
}
return 0;
}