http://acm.hdu.edu.cn/showproblem.php?pid=4453
对一个循环序列进行操作 因为k1 k2都不会超过序列长度 所以指针不变时就是一些基本操作 当指针移动时可以当做区间交换 即进行三次区间翻转
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node;
node *null;
struct node
{
node *fa,*ch[2];
int sz,rev,val,laz;
void wipe()
{
fa=ch[0]=ch[1]=null;
sz=1,val=0,laz=0,rev=0;
}
int getd()
{
return fa->ch[1]==this;
}
void setc(node *tmp,int d)
{
ch[d]=tmp;
tmp->fa=this;
}
void add(int tlaz)
{
if(this==null) return;
val+=tlaz,laz+=tlaz;
}
void reverse()
{
if(this==null) return;
swap(ch[0],ch[1]);
rev^=1;
}
void pushup()
{
sz=ch[0]->sz+ch[1]->sz+1;
}
void pushdown()
{
if(laz!=0)
{
ch[0]->add(laz);
ch[1]->add(laz);
laz=0;
}
if(rev!=0)
{
ch[0]->reverse();
ch[1]->reverse();
rev=0;
}
}
};
node pool[200010];
node *root,*tail;
int ary[100010];
int n,q,k1,k2,cnt;
void build(node *&cur,node *fa,int l,int r)
{
int m;
if(l>r) return;
m=(l+r)/2;
cur=tail++;
cur->wipe();
cur->fa=fa;
cur->val=ary[m],cur->laz=0,cur->rev=0;
build(cur->ch[0],cur,l,m-1);
build(cur->ch[1],cur,m+1,r);
cur->pushup();
}
void init()
{
node *tmp;
tail=pool;
null=tail++;
null->fa=null->ch[0]=null->ch[1]=null;
null->sz=0,null->val=0,null->laz=0,null->rev=0;
tmp=tail++;
tmp->wipe();
root=tmp;
tmp=tail++;
tmp->wipe();
root->setc(tmp,1);
build(root->ch[1]->ch[0],root->ch[1],1,n);
root->ch[1]->pushup();
root->pushup();
}
node *getkth(node *r,int k)
{
node *cur;
cur=r;
cur->pushdown();
while(cur->ch[0]->sz+1!=k)
{
if(cur->ch[0]->sz+1>k)
{
cur=cur->ch[0];
}
else
{
k-=(cur->ch[0]->sz+1);
cur=cur->ch[1];
}
cur->pushdown();
}
return cur;
}
void rotate(node *cur)
{
node *f,*ff;
int c,cc;
f=cur->fa,ff=cur->fa->fa;
f->pushdown();
cur->pushdown();
c=cur->getd(),cc=f->getd();
f->setc(cur->ch[!c],c);
cur->setc(f,!c);
if(ff->ch[cc]==f) ff->setc(cur,cc);
else cur->fa=ff;
f->pushup();
}
void splay(node *&root,node *tar,node *cur)
{
while(cur->fa!=tar)
{
if(cur->fa->fa==tar) rotate(cur);
else
{
cur->fa->fa->pushdown();
cur->fa->pushdown();
cur->pushdown();
if(cur->getd()==cur->fa->getd()) rotate(cur->fa);
else rotate(cur);
rotate(cur);
}
}
cur->pushup();
if(tar==null) root=cur;
}
void insert(node *&cur,node *fa,int val)
{
cur=tail++;
cur->wipe();
cur->fa=fa;
cur->val=val,cur->laz=0,cur->rev=0;
}
void show()
{
node *ptr;
int i;
printf("******\n");
for(i=2;i<=cnt+1;i++)
{
ptr=getkth(root,i);
printf("%d ",ptr->val);
}
printf("\n");
printf("******\n\n\n");
}
int main()
{
node *ptr;
int cas,i,l,r,x;
char op[10];
cas=1;
while(scanf("%d%d%d%d",&n,&q,&k1,&k2)!=EOF)
{
if(n==0&&q==0&&k1==0&&k2==0) break;
cnt=n;
for(i=1;i<=n;i++) scanf("%d",&ary[i]);
init();
printf("Case #%d:\n",cas++);
scanf("%d",&q);
while(q--)
{
scanf("%s",op);
if(op[0]=='a')
{
scanf("%d",&x);
splay(root,null,getkth(root,1));
splay(root,root,getkth(root,k2+2));
root->ch[1]->ch[0]->add(x);
root->ch[1]->pushup();
root->pushup();
}
else if(op[0]=='r')
{
splay(root,null,getkth(root,1));
splay(root,root,getkth(root,k1+2));
//printf("^%d %d^\n",getkth(root,1)->val,getkth(root,k1+1)->val);
root->ch[1]->ch[0]->reverse();
root->ch[1]->pushup();
root->pushup();
}
else if(op[0]=='i')
{
cnt++;
scanf("%d",&x);
splay(root,null,getkth(root,2));
splay(root,root,getkth(root,3));
insert(root->ch[1]->ch[0],root->ch[1],x);
root->ch[1]->pushup();
root->pushup();
}
else if(op[0]=='d')
{
cnt--;
splay(root,null,getkth(root,1));
splay(root,root,getkth(root,3));
root->ch[1]->ch[0]=null;
root->ch[1]->pushup();
root->pushup();
}
else if(op[0]=='m')
{
scanf("%d",&x);
if(x==1)
{
splay(root,null,getkth(root,1));
splay(root,root,getkth(root,cnt+2));
root->ch[1]->ch[0]->reverse();
root->ch[1]->pushup();
root->pushup();
//show();
splay(root,null,getkth(root,1));
splay(root,root,getkth(root,3));
root->ch[1]->ch[0]->reverse();
root->ch[1]->pushup();
root->pushup();
//show();
splay(root,null,getkth(root,2));
splay(root,root,getkth(root,cnt+2));
root->ch[1]->ch[0]->reverse();
root->ch[1]->pushup();
root->pushup();
//show();
}
else
{
splay(root,null,getkth(root,1));
splay(root,root,getkth(root,cnt+2));
root->ch[1]->ch[0]->reverse();
root->ch[1]->pushup();
root->pushup();
splay(root,null,getkth(root,1));
splay(root,root,getkth(root,cnt+1));
root->ch[1]->ch[0]->reverse();
root->ch[1]->pushup();
root->pushup();
splay(root,null,getkth(root,cnt));
splay(root,root,getkth(root,cnt+2));
root->ch[1]->ch[0]->reverse();
root->ch[1]->pushup();
root->pushup();
}
}
else
{
ptr=getkth(root,2);
printf("%d\n",ptr->val);
}
//show();
}
}
return 0;
}