题意:题目的意思很明显了 这个基本上就是要靠树来维护圆环的点删除 点循环 点询问 和区间翻转 区间加法
解法:直接无脑splay就可以了 这题基本上写出来没什么问题 就是调试需要一些方法的 我是这么调试的
用move 1 query循环一遍 然后再用move 2循环一遍 其他的直接无脑调试就可以了
复杂度大概是不能多说 不过常数不是很大 如果想小一点的话尽量少用几个find就可以了
#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 222222
#define ls ch[rt][0]
#define rs ch[rt][1]
#define rrs ch[root][1]
#define rls ch[root][0]
int n,m,k1,k2,x;
char op[111];
int ch[maxn][2],fa[maxn],val[maxn],num[maxn],root,rev[maxn],add[maxn],cnt;
void node(int rt){ls=rs=fa[rt]=rev[rt]=add[rt]=val[rt]=0;num[rt]=1;}
void up(int rt){num[rt]=num[ls]+num[rs]+1;}
void down(int rt){
if(rev[rt]){
rev[ls]^=1;rev[rs]^=1;
swap(ls,rs);rev[rt]=0;
}if(add[rt]){
add[ls]+=add[rt];add[rs]+=add[rt];
val[ls]+=add[rt];val[rs]+=add[rt];
add[rt]=0;
}
}
void rot(int rt){
int f=fa[rt],side=ch[f][1]==rt,ll=ch[rt][!side];
fa[ll]=f,ch[f][side]=ll;
fa[rt]=fa[f],ch[fa[f]][ch[fa[f]][1]==f]=rt;
fa[f]=rt;ch[rt][!side]=f;
up(f),up(rt);
}
void splay(int rt,int aim){
while(fa[rt]!=aim){
down(rt);
int f=fa[rt],ff=fa[f];
if(ff==aim)rot(rt);
if((ch[f][1]==rt)==(ch[ff][1]==f))rot(f),rot(rt);
else rot(rt),rot(rt);
}if(!aim)root=rt;
}
void find(int tot,int sub){
int rt=sub;
while(1){
down(rt);
if(num[ls]+1==tot)break;
if(num[ls]>=tot)rt=ls;
else tot-=num[ls]+1,rt=rs;
}
splay(rt,fa[sub]);
}
void query(){
find(2,root);
printf("%d\n",val[root]);
}
void _add(int x){
find(1,root);
find(k2+1,rrs);
int rt=ch[rrs][0];
if(rt)add[rt]+=x,val[rt]+=x;
}
void ins(int va){
++n;
find(2,root),find(1,rrs);
node(++cnt);ch[rrs][0]=cnt;fa[cnt]=rrs,val[cnt]=va;
up(rrs),up(root);
}
void _rev(){
find(1,root);
find(k1+1,rrs);
int rt=ch[rrs][0];
if(rt)rev[rt]^=1;
}
int del(){
find(1,root);
find(2,rrs);int rt=ch[rrs][0];
ch[rrs][0]=0;--n;
up(rrs),up(root);
return val[rt];
}
void mov(int x){
if(x==1){
find(n+1,root);int va=val[root];
fa[rrs]=0,fa[rls]=rrs,ch[rrs][0]=rls;
root=rrs;up(root);
find(1,root);find(1,rrs);
node(++cnt);
val[cnt]=va;fa[cnt]=rrs;ch[rrs][0]=cnt;
up(rrs),up(root);
}else{
int va=del();
find(n+1,root);find(1,rrs);
node(++cnt);fa[cnt]=rrs;val[cnt]=va;
ch[rrs][0]=cnt;n++;
up(rrs),up(root);
}
}
int a[maxn];
void build(){
node(0);num[0]=0;
for(int i=1;i<=n+2;++i){node(i);}cnt=n+2;
fa[n+2]=n+1;ch[n+1][1]=n+2;
for(int i=1;i<=n+1;++i){fa[i]=i+1;ch[i+1][0]=i;val[i]=a[i];up(i);}
fa[n+1]=0;root=n+1;
}int _=0;
int main(){
while(~scanf("%d%d%d%d",&n,&m,&k1,&k2)){
if(!n&&!m&&!k1&&!k2)break;printf("Case #%d:\n",++_);
for(int i=2;i<=n+1;++i)scanf("%d",&a[i]);
build();
while(m--){
scanf("%s",op);
switch(*op){
case'q':query();break;
case'i':scanf("%d",&x);ins(x);break;
case'a':scanf("%d",&x);_add(x);break;
case'm':scanf("%d",&x);mov(x);break;
case'd':del();break;
case'r':_rev();break;
}
}
}
return 0;
}