维护全局移动量什么的后可以上线段树。
思维难度低一点的做法是直接splay。。(适合我这种脑残选手
F操作就是把2~n翻转。R操作就是把后面k个元素插到最前面来。维护颜色段是老套路了。。。
比较坑的是。。多加俩边界节点的话,需要考虑有没有可能对答案造成影响。。
然而边界节点不可能在合并子区间的时候造成干扰。。
而且P操作的时候,选出来的子区间里也不会包含边界节点。。所以根本不用担心>_<
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 const int maxn=500233; 6 int ch[maxn][2],fa[maxn],lc[maxn],rc[maxn],num[maxn],sz[maxn],col[maxn]; 7 bool rev[maxn],cov[maxn]; 8 int i,j,k,n,m,x,y,rt,tot; 9 char s[23]; 10 11 int ra;char rx; 12 inline int read(){ 13 rx=getchar(),ra=0; 14 while(rx<'0'||rx>'9')rx=getchar(); 15 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 16 } 17 18 inline void pushdown(int x){ 19 int l=ch[x][0],r=ch[x][1]; 20 if(cov[x]){ 21 // if(l>1&&l<n+2) 22 if(l)col[l]=lc[l]=rc[l]=col[x],cov[l]=1,num[l]=1; 23 // if(r>1&&r<n+2) 24 if(r)col[r]=lc[r]=rc[r]=col[x],cov[r]=1,num[r]=1; 25 cov[x]=0;rev[x]=0; 26 } 27 if(rev[x]){ 28 swap(ch[x][0],ch[x][1]),rev[l]^=1,rev[r]^=1, 29 swap(lc[l],rc[l]),swap(lc[r],rc[r]), 30 rev[x]=0; 31 } 32 } 33 inline void upd(int x){ 34 int l=ch[x][0],r=ch[x][1]; 35 if(l&&r) 36 lc[x]=lc[l],rc[x]=rc[r],num[x]=num[l]+num[r]+1-(col[x]==rc[l])-(col[x]==lc[r]);else 37 if(l) 38 lc[x]=lc[l],rc[x]=col[x],num[x]=num[l]+(col[x]!=rc[l]);else 39 if(r) 40 lc[x]=col[x],rc[x]=rc[r],num[x]=num[r]+(col[x]!=lc[r]);else 41 num[x]=1,lc[x]=rc[x]=col[x]; 42 // printf(" upd: %d %d ch:%d %d ",x,num[x],l,r); 43 sz[x]=sz[l]+sz[r]+1; 44 } 45 inline void rotate(int x){ 46 int f=fa[x],gfa=fa[f],l=ch[f][1]==x,r=l^1; 47 if(f!=rt)ch[gfa][ch[gfa][1]==f]=x;else rt=x; 48 //fa[fa[fa[ch[f][l]=ch[x][r]]=ch[x][r]=f]=x]=gfa; 49 ch[f][l]=ch[x][r],ch[x][r]=f,fa[f]=x,fa[x]=gfa,fa[ch[f][l]]=f; 50 upd(f);//upd(x); 51 } 52 inline void splay(int &rt,int x){ 53 int f,gfa; 54 while(x!=rt){ 55 f=fa[x],gfa=fa[f]; 56 if(f!=rt) 57 rotate(((ch[gfa][1]==f)^(ch[f][1]==x))?x:f); 58 rotate(x); 59 } 60 upd(x); 61 } 62 63 inline int find(int x,int k){ 64 pushdown(x); 65 int l=ch[x][0]; 66 if(k<=sz[l])return find(l,k);else 67 if(k>sz[l]+1)return find(ch[x][1],k-sz[l]-1); 68 else return x; 69 } 70 inline void run_R(int k){ 71 int x=find(rt,n-k+1),y=find(rt,n+2); 72 splay(rt,x),splay(ch[x][1],y); 73 int z=ch[y][0];ch[y][0]=0,upd(y),upd(x); 74 int x1=find(rt,1),y1=find(rt,2); 75 splay(rt,x1),splay(ch[x1][1],y1); 76 ch[y1][0]=z,fa[z]=y1,upd(y1),upd(x1); 77 } 78 inline void run_F(){ 79 int x=find(rt,2),y=find(rt,n+2); 80 splay(rt,x),splay(ch[x][1],y); 81 int z=ch[y][0];//printf("! z:%d col:%d num:%d ",z,col[z],num[z]); 82 rev[z]^=1,swap(lc[z],rc[z]),upd(y),upd(x); 83 } 84 inline void run_S(int i,int j){ 85 int tmpi=i; 86 i=find(rt,i+1),splay(rt,i);int coli=col[i]; 87 j=find(rt,j+1),splay(rt,j);int colj=col[j]; 88 col[j]=coli,upd(j); 89 i=find(rt,tmpi+1),splay(rt,i),col[i]=colj,upd(i); 90 } 91 inline void run_P(int i,int j,int K){ 92 int x,y,z; 93 if(i<=j){ 94 x=find(rt,i),y=find(rt,j+2), 95 splay(rt,x),splay(ch[x][1],y), 96 z=ch[y][0],cov[z]=1,col[z]=lc[z]=rc[z]=K,num[z]=1,upd(y),upd(x); 97 }else{ 98 x=find(rt,i),y=find(rt,n+2),//printf("! x:%d %d ",x,col[x]); 99 splay(rt,x),splay(ch[x][1],y),//printf("! %d %d ",ch[y][0],col[ch[y][0]]); 100 z=ch[y][0],cov[z]=1,col[z]=lc[z]=rc[z]=K,num[z]=1,upd(y),upd(x); 101 102 x=find(rt,1),y=find(rt,j+2), 103 splay(rt,x),splay(ch[x][1],y), 104 z=ch[y][0],cov[z]=1,col[z]=lc[z]=rc[z]=K,num[z]=1,upd(y),upd(x); 105 } 106 } 107 inline int query_C(){ 108 int x,tmpcol; 109 x=find(rt,2),splay(rt,x);tmpcol=col[x]; 110 x=find(rt,n+1),splay(rt,x); 111 return max(1,num[rt]-2-(tmpcol==col[x]));//记得减去边界的0 112 } 113 inline int query_CS(int i,int j){ 114 int x,y,z; 115 if(i<=j){ 116 x=find(rt,i),y=find(rt,j+2); 117 splay(rt,x),splay(ch[x][1],y); 118 z=ch[y][0];return num[z]; 119 }else{ 120 int tmpcol,sm=0; 121 x=find(rt,i),y=find(rt,n+2), 122 splay(rt,x),splay(ch[x][1],y),z=ch[y][0]; 123 sm=num[z],tmpcol=rc[z]; 124 125 x=find(rt,1),y=find(rt,j+2), 126 splay(rt,x),splay(ch[x][1],y),z=ch[y][0]; 127 sm+=num[z]-(lc[z]==tmpcol); 128 return sm; 129 } 130 } 131 132 inline void build(int &x,int a,int b,int f){ 133 if(a>b)return; 134 x=++tot;fa[x]=f; 135 if(a==b&&a>1&&a<n+2)col[x]=lc[x]=rc[x]=read();//,printf("! %d ",a); 136 if(a==b){sz[x]=num[x]=1;return;} 137 int mid=(a+b)>>1; 138 build(ch[x][0],a,mid-1,x); 139 if(mid>1&&mid<n+2)col[x]=read(); 140 build(ch[x][1],mid+1,b,x); 141 upd(x);//printf("%d--%d %d ",a-1,b-1,num[x]); 142 } 143 /*inline void dfs(int x){ 144 pushdown(x); 145 int l=ch[x][0],r=ch[x][1]; 146 if(l)dfs(l); 147 148 // printf("%d sz:%d col:%d ",x,sz[x],col[x]); 149 // printf(" ch:%d %d lc:%d rc:%d rev:%d cov:%d ",l,r,lc[x],rc[x],rev[x],cov[x]); 150 151 if(r)dfs(r); 152 }*/ 153 154 155 int main(){ 156 n=read(),m=read(); 157 build(rt,1,n+2,0); 158 // printf("! %d ",num[rt]);printf("%d ",query_C()); 159 //printf("! %d %d ",num[rt],query_C()); 160 // dfs(rt);puts(""); 161 for(m=read();m;m--){ 162 scanf("%s",s); 163 if(s[0]=='R')x=read(),run_R(x); 164 if(s[0]=='F')run_F(); 165 if(s[0]=='S')x=read(),y=read(),run_S(x,y); 166 if(s[0]=='P')x=read(),y=read(),k=read(),run_P(x,y,k); 167 if(s[0]=='C'&&s[1]!='S')printf("%d ",query_C()); 168 if(s[0]=='C'&&s[1]=='S')x=read(),y=read(),printf("%d ",query_CS(x,y)); 169 // for(i=1;i<=n;i++)printf(" %d",col[find(rt,i+1)]);puts(""); 170 } 171 // dfs(rt);printf("!!! %d %d ",rt,sz[rt]); 172 return 0; 173 }