hdu4453
题意就是…一个环上有n个点,每个点有值,m个操作,有k1,k2两个参数
6种操作:1、add x 给此时指针指向的这个点开始的连续k2个数都加上x,指针位置不变
2、reverse 把从指针指向的这个点开始的连续k1个数翻转,指针位置不变
3、insert x 在指针指向的这个点后面加上一个值为x的点,指针位置不变
4、delete 删除指针指向的这个点,指针指向下一个数
5、move x 若x等于1,指针前移(左);若x等于2,指针后移(右)
6、query 求此时指针指向的这个点的值
做这道题…真的是…经历了人生的大起大落…
一开始看这道题..感觉….似乎..不难?就是..模板吧..然后就…写了???
然后就…改到死………..
这题….如果..move的话..就手动把数列…改了,使指针指向的永远是第一个数(如果x等于1,就把最后的数删除,插入到最前面)这样…其他操作就很简单了
讲真..我的代码能力…快要…不行了……它它它真的使模板啊(手动再见(手动再见(手动再见
#include
#include
using namespace std;
#define N 220000
int n,m,tot,root,flag1,flag2,k1,k2,size[N],ch[N][2],a[N],v[N],rev[N],flag[N],fa[N];
char str[10];
void update(int p){size[p]=size[ch[p][0]]+size[ch[p][1]]+1;}
void pushdown(int x){
if(rev[x]){
rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;rev[x]^=1;
swap(ch[x][0],ch[x][1]);
}if(flag[x]){
v[ch[x][0]]+=flag[x];v[ch[x][1]]+=flag[x];
flag[ch[x][0]]+=flag[x];flag[ch[x][1]]+=flag[x];flag[x]=0;
}
}
void push(int x){
if(fa[x]) push(fa[x]);
pushdown(x);
}
void build(int &p,int l,int r,int f){
p=++tot;ch[p][0]=ch[p][1]=flag[p]=rev[p]=0;fa[p]=f;size[p]=1;
int mid=l+r>>1;v[p]=a[mid];
if(mid==1) flag1=p;if(mid==n+2) flag2=p;
if(l==r) return;
if(l0],l,mid-1,p);
if(mid1],mid+1,r,p);
update(p);
}
void rotate(int &x){
int y=fa[x],z=fa[y],t=ch[y][0]==x;
if(z) ch[z][ch[z][1]==y]=x;
else root=x;
fa[x]=z;fa[y]=x;fa[ch[x][t]]=y;
ch[y][t^1]=ch[x][t];ch[x][t]=y;
update(y);update(x);
}
void splay(int x,int &rt){
push(x);
while(x!=rt){
int y=fa[x];
if(y==rt){rotate(x);return;}
if(ch[y][0]==x^ch[fa[y]][0]==y) rotate(x);
else rotate(y);rotate(x);
}
}
int find(int p,int x){
pushdown(p);
if(x<=size[ch[p][0]]) return find(ch[p][0],x);x-=size[ch[p][0]];
if(x==1) return p;
return find(ch[p][1],x-1);
}
void query(){
int x=find(root,2);printf("%d\n",v[x]);
}
int del(int xx){
int x=find(root,xx-1),y=find(root,xx+1);
splay(x,root);splay(y,ch[x][1]);
int z=ch[y][0];ch[y][0]=0;
update(y);update(x);
return z;
}
void add(int z){
int x=flag1,y=find(root,k2+2);
splay(x,root);splay(y,ch[x][1]);
flag[ch[y][0]]+=z;v[ch[y][0]]+=z;
}
void rev1(){
int x=flag1,y=find(root,k1+2);
splay(x,root);splay(y,ch[x][1]);
rev[ch[y][0]]^=1;
}
void insert(int x,int y){
int xx=find(root,x),yy=find(root,x+1);
splay(xx,root);splay(yy,ch[xx][1]);
ch[yy][0]=y;fa[y]=yy;update(yy);update(xx);
}
int main(){
int cnt=0;
while(1){
scanf("%d %d %d %d",&n,&m,&k1,&k2);
if(n==0) return 0;
printf("Case #%d:\n",++cnt);
for(int i=2;i<=n+1;i++) scanf("%d",&a[i]);
tot=0;root=0;build(root,1,n+2,0);
for(int i=1;i<=m;i++){
scanf("%s",str);
if(str[0]=='m'){
int x;scanf("%d",&x);
if(x==1){int y=del(size[root]-1);insert(1,y);}
else{int y=del(2);insert(size[root]-1,y);}
}else if(str[0]=='i'){
int x;scanf("%d",&x);
v[++tot]=x;ch[tot][0]=ch[tot][1]=fa[tot]=rev[tot]=flag[tot]=0;size[tot]=1;
insert(2,tot);
}else if(str[0]=='r') rev1();
else if(str[0]=='a'){
int x;scanf("%d",&x);
add(x);
}else if(str[0]=='d') del(2);
else if(str[0]=='q') query();
}
}
return 0;
}