题目描述
题解
splay模板题啦啦啦。
由于加了一个前驱和一个后继所以算编号的时候要小心一点。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 300005
#define inf 2100000000
int n,m,x,y,d,t,p,root,sz;
int a[N],f[N],ch[N][2],size[N],Min[N],key[N],add[N],rev[N];
char opt[20];
void clear(int x)
{
f[x]=ch[x][0]=ch[x][1]=size[x]=Min[x]=key[x]=add[x]=rev[x]=0;
}
int get(int x)
{
return ch[f[x]][1]==x;
}
void update(int x)
{
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
Min[x]=key[x];
if (ch[x][0]) Min[x]=min(Min[x],Min[ch[x][0]]);
if (ch[x][1]) Min[x]=min(Min[x],Min[ch[x][1]]);
}
void pushdown(int x)
{
if (x)
{
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];
Min[ch[x][0]]+=add[x];Min[ch[x][1]]+=add[x];
key[ch[x][0]]+=add[x];key[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)>>1,now=++sz;
f[sz]=fa;key[sz]=a[mid];
int lch=build(l,mid-1,now);
int rch=build(mid+1,r,now);
ch[now][0]=lch,ch[now][1]=rch;
update(now);
return now;
}
void rotate(int x)
{
pushdown(f[x]);
pushdown(x);
int old=f[x],oldf=f[old],wh=get(x);
ch[old][wh]=ch[x][wh^1];
f[ch[old][wh]]=old;
ch[x][wh^1]=old;
f[old]=x;
if (oldf) ch[oldf][ch[oldf][1]==old]=x;
f[x]=oldf;
update(old);
update(x);
}
void splay(int x,int tar)
{
for (int fa;(fa=f[x])!=tar;rotate(x))
if (f[fa]!=tar)
rotate( (get(x)==get(fa))?fa:x );
if (!tar) root=x;
}
int find(int x)
{
int now=root;
while (1)
{
pushdown(now);
if (x<=size[ch[now][0]]) now=ch[now][0];
else
{
x-=size[ch[now][0]];
if (x==1) return now;
--x;
now=ch[now][1];
}
}
}
int main()
{
scanf("%d",&n);
a[1]=-inf;a[n+2]=inf;
for (int i=1;i<=n;++i) scanf("%d",&a[i+1]);
root=build(1,n+2,0);
scanf("%d",&m);
for (int i=1;i<=m;++i)
{
scanf("%s",opt);
switch(opt[0])
{
case 'A':
{
scanf("%d%d%d",&x,&y,&d);
if (x>y) swap(x,y);
int aa=find(x);
int bb=find(y+2);
splay(aa,0);
splay(bb,aa);
Min[ch[ch[root][1]][0]]+=d;
add[ch[ch[root][1]][0]]+=d;
key[ch[ch[root][1]][0]]+=d;
update(ch[root][1]);
update(root);
break;
}
case 'R':
{
if (opt[3]=='E')
{
scanf("%d%d",&x,&y);
if (x==y) continue;
if (x>y) swap(x,y);
int aa=find(x);
int bb=find(y+2);
splay(aa,0);
splay(bb,aa);
rev[ch[ch[root][1]][0]]^=1;
}
else
{
scanf("%d%d%d",&x,&y,&t);
if (x>y) swap(x,y);
t%=y-x+1;
if (!t) continue;
int aa=find(y-t+1);
int bb=find(y+2);
splay(aa,0);
splay(bb,aa);
int now=ch[ch[root][1]][0];
ch[ch[root][1]][0]=0;
update(ch[root][1]);
update(root);
aa=find(x);
bb=find(x+1);
splay(aa,0);
splay(bb,aa);
ch[ch[root][1]][0]=now;
f[now]=ch[root][1];
update(ch[root][1]);
update(root);
}
break;
}
case 'I':
{
scanf("%d%d",&x,&p);
int aa=find(x+1);
int bb=find(x+2);
splay(aa,0);
splay(bb,aa);
ch[ch[root][1]][0]=++sz;
f[sz]=ch[root][1];
key[sz]=Min[sz]=p;
size[sz]=1;
update(ch[root][1]);
update(root);
break;
}
case 'D':
{
scanf("%d",&x);
int aa=find(x);
int bb=find(x+2);
splay(aa,0);
splay(bb,aa);
int del=ch[ch[root][1]][0];
clear(del);
ch[ch[root][1]][0]=0;
update(ch[root][1]);
update(root);
break;
}
case 'M':
{
scanf("%d%d",&x,&y);
if (x>y) swap(x,y);
int aa=find(x);
int bb=find(y+2);
splay(aa,0);
splay(bb,aa);
int ans=Min[ch[ch[root][1]][0]];
printf("%d\n",ans);
break;
}
}
}
}