传送门
发现题目中的所有东西都可以用splay维护
然后就理所应当的成了splay裸题了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#define N 300030
using namespace std;
int n,m,x,y,d,t,p,rt,cnt;
int a[N],f[N],ch[N][2],sz[N],mn[N],key[N],add[N],rev[N];
char s[20];
void clear(int x){
f[x]=ch[x][0]=ch[x][1]=sz[x]=0;
mn[x]=key[x]=add[x]=rev[x]=0;
}
int get(int x){
return ch[f[x]][1]==x;
}
void update(int x){
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
mn[x]=key[x];
if (ch[x][0]) mn[x]=min(mn[x],mn[ch[x][0]]);
if (ch[x][1]) mn[x]=min(mn[x],mn[ch[x][1]]);
}
void pushdown(int x){
if (!x) return;
if (rev[x]){
rev[ch[x][0]]^=1;
rev[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
rev[x]=0;
}
if (add[x]){
add[ch[x][0]]+=add[x],add[ch[x][1]]+=add[x];
key[ch[x][0]]+=add[x],key[ch[x][1]]+=add[x];
mn[ch[x][0]]+=add[x],mn[ch[x][1]]+=add[x];
add[x]=0;
}
}
int build(int l,int r,int fa){
if (l>r) return 0;
int mid=(l+r)/2,x=++cnt;
f[x]=fa; key[x]=a[mid];
ch[x][0]=build(l,mid-1,x);
ch[x][1]=build(mid+1,r,x);
update(x);
return x;
}
void rotate(int x){
pushdown(f[x]); pushdown(x);
int y=f[x],z=f[y],l=get(x),r=l^1;
if (z) ch[z][get(y)]=x;
f[x]=z; f[y]=x; f[ch[x][r]]=y;
ch[y][l]=ch[x][r]; ch[x][r]=y;
update(y); update(x);
}
void splay(int x,int tar){
for (;f[x]!=tar;rotate(x))
if (f[f[x]]!=tar)
rotate(get(x)==get(f[x])?f[x]:x);
if (!tar) rt=x;
}
int find(int rk){
int x=rt;
while(1){
pushdown(x);
if (rk<=sz[ch[x][0]]) x=ch[x][0];
else{
rk-=sz[ch[x][0]]+1;
if (!rk) return x;
x=ch[x][1];
}
}
}
void pre(int x,int y){
int a=find(x),b=find(y);
splay(a,0); splay(b,a);
}
void up(){
update(ch[rt][1]);
update(rt);
}
int main(){
scanf("%d",&n);
a[1]=2e9; a[n+2]=-2e9;
for (int i=2;i<=n+1;i++) scanf("%d",&a[i]);
rt=build(1,n+2,0);
scanf("%d",&m);
while (m--){
scanf("%s",s);
if (s[0]=='A'){
scanf("%d%d%d",&x,&y,&d);
if (x>y) swap(x,y);
pre(x,y+2);
mn[ch[ch[rt][1]][0]]+=d;
add[ch[ch[rt][1]][0]]+=d;
key[ch[ch[rt][1]][0]]+=d;
up();
}
else if (s[0]=='I'){
scanf("%d%d",&x,&p);
pre(x+1,x+2);
ch[ch[rt][1]][0]=++cnt;
f[cnt]=ch[rt][1];
key[cnt]=mn[cnt]=p;
sz[cnt]=1;
up();
}
else if (s[0]=='D'){
scanf("%d",&x);
pre(x,x+2);
int del=ch[ch[rt][1]][0];
clear(del);
ch[ch[rt][1]][0]=0;
up();
}
else if (s[0]=='M'){
scanf("%d%d",&x,&y);
if (x>y) swap(x,y);
pre(x,y+2);
printf("%d\n",mn[ch[ch[rt][1]][0]]);
}
else if (s[3]=='E'){
scanf("%d%d",&x,&y);
if (x==y) continue;
pre(x,y+2);
rev[ch[ch[rt][1]][0]]^=1;
}
else{
scanf("%d%d%d",&x,&y,&t);
if (x>y) swap(x,y);
t%=(y-x+1);
if (!t) continue;
pre(y-t+1,y+2);
int now=ch[ch[rt][1]][0];
ch[ch[rt][1]][0]=0;
up();
pre(x,x+1);
ch[ch[rt][1]][0]=now;
f[now]=ch[rt][1];
up();
}
}
}