很完整的splay操作。做了这题就可以当板子用了。
#include <cstdio>
#include <algorithm>
#include <cstring> using namespace std; #define Key_value ch[ch[root][1] ][0] const int maxn = 5e5+;
const int INF = 0x3f3f3f3f; int pre[maxn],ch[maxn][],key[maxn],sz[maxn];
int root,tot1;
int rev[maxn],mi[maxn],add[maxn];
int s[maxn],tot2;
int a[maxn];
int n,q; void Treavel(int x)
{
if(x)
{
Treavel(ch[x][]);
printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d size= %2d mi=%2d add=%2d\n",x,ch[x][],ch[x][],pre[x],key[x],sz[x],mi[x],add[x]);
Treavel(ch[x][]);
}
}
void debug()
{
printf("root:%d\n",root);
Treavel(root);
}
// void NewNode(int &r,int father,int k)
{
if(tot2) r = s[tot2--];
else r = ++tot1;
pre[r] = father;
ch[r][] = ch[r][] = ;
key[r] = k;
mi[r] = k;
rev[r] = add[r] = ;
sz[r] = ;
} void Update_add(int r,int c)
{
if(!r) return ;
key[r] += c;
mi[r] += c;
add[r] += c;
} void Update_rev(int r)
{
if(!r) return ;
swap(ch[r][],ch[r][]);
rev[r] ^= ;
} void push_up(int r)
{
int lson = ch[r][],rson = ch[r][];
sz[r] = sz[lson] + sz[rson] + ;
mi[r] = min(min(mi[lson],mi[rson]),key[r]);
} void push_down(int r)
{
if(rev[r])
{
Update_rev(ch[r][]);
Update_rev(ch[r][]);
rev[r] = ;
}
if(add[r])
{
Update_add(ch[r][],add[r]);
Update_add(ch[r][],add[r]);
add[r] = ;
}
} void Build(int &x,int l,int r,int father)
{
if(l>r) return ;
int mid = (l+r)>>;
NewNode(x,father,a[mid]);
Build(ch[x][],l,mid-,x);
Build(ch[x][],mid+,r,x);
push_up(x);
} void Init()
{
root = tot1 = tot2 = ;
ch[root][] = ch[root][] = sz[root] = pre[root] = ;
rev[root] = key[root] = ;
mi[root] = INF;
NewNode(root,,);
NewNode(ch[root][],root,);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
Build(Key_value,,n,ch[root][]);
push_up(ch[root][]);
push_up(root);
}
void Rotate(int x,int kind)
{
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind] ] = y;
if(pre[y])
ch[pre[y] ][ch[pre[y]][]==y ] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
}
void Splay(int r,int goal)
{
push_down(r);
while(pre[r] != goal)
{
if(pre[pre[r] ] == goal)
{
push_down(pre[r]);
push_down(r);
Rotate(r,ch[pre[r]][] == r);
}
else
{
push_down(pre[pre[r] ]);
push_down(pre[r]);
push_down(r);
int y = pre[r];
int kind = ch[pre[y] ][] == y;
if(ch[y][kind] == r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
push_up(r);
if(goal == ) root = r;
}
} int Get_kth(int r,int k)
{
push_down(r);
int t = sz[ch[r][] ] + ;
if(t == k) return r;
if(t > k) return Get_kth(ch[r][],k);
else return Get_kth(ch[r][],k-t);
} void Insert(int pos,int tot)
{
for(int i=;i<tot;i++) scanf("%d",&a[i]);
Splay(Get_kth(root,pos+) , );
Splay(Get_kth(root,pos+) , root);
Build(Key_value,,tot-,ch[root][]);
push_up(ch[root][]);
push_up(root);
}
void erase(int r)
{
if(!r) return ;
s[++tot2] = r;
erase(ch[r][]);
erase(ch[r][]);
}
void Delete(int pos,int tot)
{
Splay(Get_kth(root,pos) ,);
Splay(Get_kth(root,pos+tot+) , root);
erase(Key_value);
pre[Key_value] = ;
Key_value = ;
push_up(ch[root][]);
push_up(root);
} void Reverse(int pos,int tot)
{
Splay(Get_kth(root,pos) , );
Splay(Get_kth(root,pos+tot+), root);
Update_rev(Key_value);
} void Add(int pos,int tot,int c)
{
Splay(Get_kth(root,pos) , );
Splay(Get_kth(root,pos+tot+) , root);
Update_add(Key_value,c);
push_up(ch[root][]);
push_up(root);
} int Get_min(int pos,int tot)
{
Splay(Get_kth(root,pos) , );
Splay(Get_kth(root,pos+tot+) , root);
return mi[Key_value];
} void Revolve(int l,int r,int t)
{
if(!t) return ;
int c = r - t;
Splay(Get_kth(root,l) , );
Splay(Get_kth(root,c+),root);
int tmp = Key_value;
Key_value = ;
push_up(ch[root][]);
push_up(root);
Splay(Get_kth(root,r-c+l) , );
Splay(Get_kth(root,r-c+l+) , root);
Key_value = tmp;
pre[Key_value] = ch[root][];
push_up(ch[root][]);
push_up(root);
} int m;
int main()
{
while(~scanf("%d ",&n))
{
Init();
//debug();
scanf("%d ",&m);
char op[];
for(int i=;i<m;i++)
{
scanf(" %s",op);
//printf("i:%d op:%s\n",i,op);
int x,y,c,t;
if(op[] == 'A') //add
{
scanf("%d%d%d",&x,&y,&c);
Add(x,y-x+,c);
}
else if(op[] == 'I') //insert
{
scanf("%d",&x);
Insert(x,);
}
else if(op[] == 'D') //delete
{
scanf("%d",&x);
Delete(x,);
}
else if(op[] == 'M') //min
{
scanf("%d%d",&x,&y);
printf("%d\n",Get_min(x,y-x+));
}
else if(op[] == 'R' && op[] == 'E')//reverse
{
scanf("%d%d",&x,&y);
Reverse(x,y-x+);
}
else //revolve
{
scanf("%d%d%d",&x,&y,&t);
t = (t%(y-x+)+(y-x+))%(y-x+);
Revolve(x,y,t);
}
//debug();
}
}
}