题意:维护序列,支持区间增值,区间翻转,区间循环位移,插入,删除,区间最小
用来练treap,果然treap在这种题上就是好写,根本不用考虑什么特殊情况,直接无脑split,merge就行了
循环位移这个东西,找到区间之后分成对应的两半,反着merge就可以了
啊啊啊merge的时候一定要pushdown啊要不然会WA到飞起啊
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int l[200010],r[200010],v[200010],fix[200010],siz[200010],ad[200010],rv[200010],ms[200010],rt,tot;
int min(int a,int b){return a<b?a:b;}
void swap(int&a,int&b){a^=b^=a^=b;}
void pushup(int x){
siz[x]=siz[l[x]]+siz[r[x]]+1;
ms[x]=min(v[x],min(ms[l[x]],ms[r[x]]));
}
void rev(int x){
rv[x]^=1;
swap(l[x],r[x]);
}
void add(int x,int d){
v[x]+=d;
ad[x]+=d;
ms[x]+=d;
}
void pushdown(int x){
if(rv[x]){
if(l[x])rev(l[x]);
if(r[x])rev(r[x]);
rv[x]=0;
}
if(ad[x]){
if(l[x])add(l[x],ad[x]);
if(r[x])add(r[x],ad[x]);
ad[x]=0;
}
}
struct pair{
int l,r;
pair(int a=0,int b=0){l=a;r=b;}
};
pair split(int x,int k){
if(x==0)return pair();
pair s;
pushdown(x);
if(k<=siz[l[x]]){
s=split(l[x],k);
l[x]=s.r;
s.r=x;
}else{
s=split(r[x],k-siz[l[x]]-1);
r[x]=s.l;
s.l=x;
}
pushup(x);
return s;
}
int merge(int x,int y){
if(x==0)return y;
if(y==0)return x;
pushdown(x);
pushdown(y);
if(fix[x]<fix[y]){
r[x]=merge(r[x],y);
pushup(x);
return x;
}else{
l[y]=merge(x,l[y]);
pushup(y);
return y;
}
}
void plus(int l,int r,int d){
pair s,t;
s=split(rt,l-1);
t=split(s.r,r-l+1);
add(t.l,d);
rt=merge(s.l,merge(t.l,t.r));
}
void reverse(int l,int r){
pair s,t;
s=split(rt,l-1);
t=split(s.r,r-l+1);
rev(t.l);
rt=merge(s.l,merge(t.l,t.r));
}
void revolve(int l,int r,int k){
k%=(r-l+1);
pair s,pl,pr;
s=split(rt,r-k);
pl=split(s.l,l-1);
pr=split(s.r,k);
rt=merge(merge(pl.l,pr.l),merge(pl.r,pr.r));
}
void insert(int p,int d){
pair s=split(rt,p);
tot++;
fix[tot]=rand()*rand();
siz[tot]=1;
v[tot]=ms[tot]=d;
rt=merge(s.l,merge(tot,s.r));
}
void erase(int p){
pair s,t;
s=split(rt,p-1);
t=split(s.r,1);
rt=merge(s.l,t.r);
}
int query(int l,int r){
pair s,t;
s=split(rt,l-1);
t=split(s.r,r-l+1);
int ans=ms[t.l];
rt=merge(s.l,merge(t.l,t.r));
return ans;
}
int main(){
srand(time(0));
ms[0]=2147483647;
int n,m,i,l,r,v;
char s[10];
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&v);
insert(i,v);
}
scanf("%d",&m);
while(m--){
scanf("%s",s);
if(s[0]==‘A‘){
scanf("%d%d%d",&l,&r,&v);
plus(l,r,v);
}
if(s[0]==‘R‘&&s[3]==‘E‘){
scanf("%d%d",&l,&r);
reverse(l,r);
}
if(s[3]==‘O‘){
scanf("%d%d%d",&l,&r,&v);
revolve(l,r,v);
}
if(s[0]==‘I‘){
scanf("%d%d",&l,&v);
insert(l,v);
}
if(s[0]==‘D‘){
scanf("%d",&l);
erase(l);
}
if(s[0]==‘M‘){
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r));
}
}
}