思路:
\(FHQ\_treap\ or\ Splay板题\)
每个节点需保存当前节点值,子树最小值,反转标记,增加标记。
对于操作\(4.5,\)直接插入/删除
对于操作\(1,\)先提取区间\([l,r]\),再打上增加标记
对于操作\(2,\)先提取区间\([l,r]\),再打上翻转标记
对于操作\(3,\)先提取区间\([l,r-T\%(r-l+1)-l+1]\),直接交换左右子树
对于操作\(6,\)先提取区间\([l,r]\),返回最小值
\(\mathfrak{Talk\ is\ cheap,show\ you\ the\ code.}\)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
# define Type template<typename T>
# define read read1<int>()
Type inline T read1()
{
T t=0;
bool ty=0;
char k;
do k=getchar(),(k=='-')&&(ty=1);while('0'>k||k>'9');
do t=(t<<3)+(t<<1)+(k^'0'),k=getchar();while('0'<=k&&k<='9');
return ty?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
template<typename T,typename _T>
class FHQ_treap_map
{
private:
int seed,space;
public:
int Rand(){return seed=seed*33457+52331314;}
class node
{
public:
node *l,*r;
T k;_T v;bool fl;
int cnt,si,q,ad;
node(){l=r=NULL;cnt=si=1;fl=ad=0;}
node(T k1,_T v1,int q1){l=r=NULL;cnt=si=1;k=k1;v=v1;q=q1;fl=ad=0;}
}*root;
class Pair
{
public:
node *l,*r;
Pair(){}
Pair(node *a,node *b){l=a;r=b;}
};
private:
_T value(node *n){return n?n->v:1<<30;}
void pushup(node *n){n->si=size(n->l)+size(n->r)+n->cnt;n->v=min(value(n->l),min(value(n->r),n->k));}
void turn(node *n){if(n)n->fl^=1;}
void ad(node *n,int m){if(n)n->ad+=m,n->k+=m,n->v+=m;}
void pushdown(node *n){if(n->fl)turn(n->l),turn(n->r),swap(n->l,n->r);ad(n->l,n->ad),ad(n->r,n->ad),n->ad=n->fl=0;}
int size(node *n){return n?n->si:0;}
Pair split(node *n,int ra)
{
if(!n)return Pair(NULL,NULL);
Pair tem;
pushdown(n);
if(ra<=size(n->l))
{
tem=split(n->l,ra);
n->l=tem.r;
tem.r=n;
}
else
{
tem=split(n->r,ra-size(n->l)-n->cnt);
n->r=tem.l;
tem.l=n;
}
pushup(n);
return tem;
}
Pair _split(node *n,T v)
{
if(!n)return Pair(NULL,NULL);
Pair tem;
pushdown(n);
if(v<n->k)
{
tem=_split(n->l,v);
n->l=tem.r;
tem.r=n;
}
else
{
tem=_split(n->r,v);
n->r=tem.l;
tem.l=n;
}
pushup(n);
return tem;
}
Pair split_(node *n,T v)
{
if(!n)return Pair(NULL,NULL);
Pair tem;
pushdown(n);
if(v<=n->k)
{
tem=split_(n->l,v);
n->l=tem.r;
tem.r=n;
}
else
{
tem=split_(n->r,v);
n->r=tem.l;
tem.l=n;
}
pushup(n);
return tem;
}
node* merge(node *l,node *r)
{
if(!l or !r)return l?l:r;
pushdown(l);
pushdown(r);
node* re;
if(l->q<r->q)l->r=merge(l->r,r),re=l;
else r->l=merge(l,r->l),re=r;
pushup(re);
return re;
}
node* findmin(node* n){while(n->l)n=n->l;return n;}
node* findmax(node* n){while(n->r)n=n->r;return n;}
public:
FHQ_treap_map(){root=NULL;seed=4088;}
void insert(T ke,_T va)
{
++space;
Pair tem=_split(root,ke);
root=merge(merge(tem.l,new node(ke,va,Rand())),tem.r);
}
void _insert(int n,T ke,_T va)
{
++space;
Pair tem=split(root,n);
root=merge(merge(tem.l,new node(ke,va,Rand())),tem.r);
}
void del(T ke)
{
--space;
Pair tem=_split(root,ke),tem1=split_(tem.l,ke);
root=merge(tem1.l,tem.r);
}
void _del(int n)
{
--space;
Pair tem=split(root,n),tem1=split(tem.l,n-1);
root=merge(tem1.l,tem.r);
}
T upper(T ke)
{
Pair tem=_split(root,ke);
T tans=findmin(tem.r)->k;
merge(tem.l,tem.r);
return tans;
}
T lower(T ke)
{
Pair tem=split_(root,ke);
T tans=findmax(tem.l)->k;
merge(tem.l,tem.r);
return tans;
}
int findrank(T ke)
{
Pair tem=split_(root,ke);
int tans=size(tem.l)+1;
merge(tem.l,tem.r);
return tans;
}
T findwho(int n)
{
for(node* i=root;i;)
if(n<=size(i->l))i=i->l;
else if(size(i->l)+i->cnt<n)n-=size(i->l)+i->cnt,i=i->r;
else return i->k;
return 0;
}
bool find(T n)
{
for(node* i=root;i;)
if(i->k==n)return 1;
else if(i->k>n)i=i->l;
else i=i->r;
return 0;
}
_T operator [] (const T n)
{
for(node* i=root;i;)
if(i->k==n)return i->v;
else if(i->k>n)i=i->l;
else i=i->r;
return root->v;
}
_T query(int l,int r)
{
Pair tem=split(root,l-1),tem1=split(tem.r,r-l+1);
_T va=value(tem1.l);
merge(merge(tem.l,tem1.l),tem1.r);
return va;
}
void add(int l,int r,int x)
{
Pair tem=split(root,l-1),tem1=split(tem.r,r-l+1);
tem1.l->k+=x;tem1.l->ad+=x;pushdown(tem1.l);
pushup(tem1.l);
merge(merge(tem.l,tem1.l),tem1.r);
}
void jump(int l,int r)
{
Pair tem=split(root,l-1),tem1=split(tem.r,r-l+1);
tem1.l->fl^=1;
merge(merge(tem.l,tem1.l),tem1.r);
}
void rev(int l,int r,int k)
{
k%=r-l+1;
if(!k)return;
Pair tem=split(root,l-1),tem1=split(tem.r,r-l+1),tem2=split(tem1.l,(r-k)-l+1);
merge(merge(tem.l,merge(tem2.r,tem2.l)),tem1.r);
}
};
FHQ_treap_map<int,int>tr;
char str[10];
int main()
{
int s=read,x,y;
for(int i=0;i++^s;)tr._insert(i-1,x,x=read);
for(int m=read;m--;)
{
scanf("%s",str);
switch(*str)
{
case 'A':x=read,y=read,tr.add(x,y,read);break;
case 'R':
{
if(*(str+3)=='E')x=read,tr.jump(x,read);
else x=read,y=read,tr.rev(x,y,read);
break;
}
case 'I':x=read,tr._insert(x,y,y=read);break;
case 'D':tr._del(read);break;
default:x=read,printf("%d\n",tr.query(x,read));
}
}
return 0;
}