初始时给出一个序列,进行一下操作:
ADD x y D [x,y] 区间每个元素增加D
REVERSE x y 翻转区间[x,y]
REVOLVE x y t 区间[x,y]循环右移t位。
INSERT x p 在x之后插入p
DELETE x 删除元素x
MIN x y 询问区间[x,y]的最小值
注意REVOLVE 可以转化成3次REVERSE或者一次
ADD 和RECERSE采用lazy标记,每次更新两层
代码:
/*************************************************************************
> File Name: Spaly.cpp
> Author: acvcla
> QQ:
> Mail: acvcla@gmail.com
> Created Time: 2014Äê11ÔÂ16ÈÕ ÐÇÆÚÈÕ 00ʱ14·Ö26Ãë
************************************************************************/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<cstdlib>
#include<ctime>
#include<set>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 2e5 + 100;
const int inf=1e9+7;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
int ch[maxn][2],pre[maxn],rev[maxn],siz[maxn],Min[maxn];
int root,tot;
int addv[maxn],A[maxn],tmp[maxn];
void newnode(int &x,int fa,int k)
{
x=++tot;
A[x]=k;
Min[x]=k;
siz[x]=1;
pre[x]=fa;
addv[x]=rev[x]=ch[x][1]=ch[x][0]=0;
}
void push_up(int x){
if(!x)return;
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
Min[x]=min(Min[ch[x][0]],Min[ch[x][1]]);
Min[x]=min(Min[x],A[x]);
}
void upadte_rev(int x)
{
if(!x)return ;
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
void Modify(int x,int val){
if(!x)return;
A[x]+=val;
Min[x]+=val;
addv[x]+=val;
}
void push_down(int x)
{
if(!x)return;
if(addv[x]){
Modify(ch[x][0],addv[x]);
Modify(ch[x][1],addv[x]);
addv[x]=0;
}
if(rev[x]){
upadte_rev(ch[x][0]);
upadte_rev(ch[x][1]);
rev[x]^=1;
}
}
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;
ch[x][kind]=y;
if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
pre[y]=x;
push_up(y);
push_up(x);
}
void Splay(int x,int goal)
{
while(pre[x]!=goal){
if(pre[pre[x]]==goal)Rotate(x,ch[pre[x]][0]==x);
else{
int y=pre[x];
int kind=(ch[pre[y]][0]==y);
if(ch[y][kind]==x){
Rotate(x,!kind);
Rotate(x,kind);
}else{
Rotate(y,kind);
Rotate(x,kind);
}
}
}
if(goal==0)root=x;
}
void built(int &x,int L,int R,int fa)
{
if(L>R)return;
int mid=(R+L)>>1;
newnode(x,fa,tmp[mid]);
built(ch[x][0],L,mid-1,x);
built(ch[x][1],mid+1,R,x);
push_up(x);
}
void init(int n)
{
siz[0]=pre[0]=0;
root=tot=ch[0][0]=ch[0][1]=0;
Min[0]=inf;
newnode(root,0,inf);
newnode(ch[root][1],root,inf);
for(int i=1;i<=n;i++)scanf("%d",tmp+i);
built(ch[ch[root][1]][0],1,n,ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
int Get_kth(int x,int k){
push_down(x);
int sz=siz[ch[x][0]]+1;
if(sz==k)return x;
if(sz>k)return Get_kth(ch[x][0],k);
return Get_kth(ch[x][1],k-sz);
}
int Get_max(int x)
{
push_down(x);
while(ch[x][1])
{
x=ch[x][1];
push_down(x);
}
return x;
}
void add(int L,int R,int v)
{
Splay(Get_kth(root,L-1),0);
Splay(Get_kth(root,R+1),root);
Modify(ch[ch[root][1]][0],v);
}
void reverse(int L,int R)
{
Splay(Get_kth(root,L-1),0);
Splay(Get_kth(root,R+1),root);
upadte_rev(ch[ch[root][1]][0]);
}
void revolve(int L,int R,int c)
{
c %= (R-L+1);
if (!c)return;
reverse(L,R);
reverse(L,L+c-1);
reverse(L+c,R);
}
void Insert(int x,int p)
{
Splay(Get_kth(root,x),0);
Splay(Get_kth(root,x+1),root);
newnode(ch[ch[root][1]][0],ch[root][1],p);
push_up(ch[root][1]);
push_up(root);
}
void remove_root()
{
push_down(root);
if(!ch[root][0]){
root=ch[root][1];
}else{
int t=Get_max(ch[root][0]);
Splay(t,root);
ch[t][1]=ch[root][1];
pre[ch[root][1]]=t;
root=t;
}
pre[root]=0;
push_up(root);
}
void del(int x)
{
Splay(Get_kth(root,x),0);
remove_root();
}
int Query(int L,int R)
{
Splay(Get_kth(root,L-1),0);
Splay(Get_kth(root,R+1),root);
return Min[ch[ch[root][1]][0]];
}
int main(int argc, char const *argv[])
{
int n,m,L,R,x;
scanf("%d",&n);
init(n);
scanf("%d",&m);
char op[10];
while(m--){
scanf("%s",op);
if(op[0]=='A'){
scanf("%d%d%d",&L,&R,&x);
add(L+1,R+1,x);
}else if(op[0]=='D'){
scanf("%d",&L);
del(L+1);
}else if(op[0]=='I'){
scanf("%d%d",&L,&x);
Insert(L+1,x);
}else if(op[0]=='M'){
scanf("%d%d",&L,&R);
printf("%d\n",Query(L+1,R+1));
}else if(op[0]=='R'){
if(op[3]=='E'){
scanf("%d%d",&L,&R);
reverse(L+1,R+1);
}else{
scanf("%d%d%d",&L,&R,&x);
revolve(L+1,R+1,x);
}
}
}
return 0;
}原文地址:http://blog.csdn.net/acvcla/article/details/41662139