题目描述
 
传送门
 
题目大意:  有一列数列,支持以下操作  对于一列数,相邻一段中最大和最小的两个数的差值称为区间极差。  merge x e 当前第 x 个数和第 x+1 个数合并,得到值为 e 的新数;  insert x e 在当前第 x 个数和第 x+1 个数之间插入一个能量为 e 的新数。  max x y 当前第 x 到第 y 个原子之间的任意子区间中区间极差的最大值;  min x y 当前第 x 到第 y 个原子之间的任意子区间中区间极差的最小值。
 
题解
 
用splay维护:子树大小,区间最大最小值,区间最左端最右端的数值,相邻两个元素差值的最小值  因为min操作实际上就是查询相邻两个元素差值的最小值  其余的随便做咯
 
代码
 
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using 
namespace std;
#define N 
200005
#define inf 
1000000001
int n,m,root,sz,a[N];
int f[N],ch[N][
2],key[N],
size[N],
ls[N],rs[N],maxn[N],minn[N],cha[N];
char opt[
10];
int Abs(
int x){
return (x>
0)?x:-x;}
void update(
int x)
{
    
int l=ch[x][
0],r=ch[x][
1];
    
size[x]=
1;cha[x]=inf;
    maxn[x]=minn[x]=
ls[x]=rs[x]=key[x];
    
if (l)
    {
        
ls[x]=
ls[l];
size[x]+=
size[l];
        maxn[x]=
max(maxn[x],maxn[l]);
        minn[x]=
min(minn[x],minn[l]);
        cha[x]=
min(cha[x],cha[l]);
        cha[x]=
min(cha[x],Abs(key[x]-rs[l]));
    }
    
if (r)
    {
        rs[x]=rs[r];
size[x]+=
size[r];
        maxn[x]=
max(maxn[x],maxn[r]);
        minn[x]=
min(minn[x],minn[r]);
        cha[x]=
min(cha[x],cha[r]);
        cha[x]=
min(cha[x],Abs(key[x]-
ls[r]));
    }
}
int build(
int l,
int r,
int fa)
{
    
if (l>r) 
return 0;
    
int mid=(l+r)>>
1;
    f[mid]=fa;key[mid]=a[mid];
    
int lch=build(l,mid-
1,mid);
    
int rch=build(mid+
1,r,mid);
    ch[mid][
0]=lch;ch[mid][
1]=rch;
    update(mid);
    
return mid;
}
int get(
int x){
return ch[f[x]][
1]==x;}
void 
rotate(
int x)
{
    
int old=f[x],oldf=f[old],wh=get(x);
    ch[old][wh]=ch[x][wh^
1];
    
if (ch[old][wh]) 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)
    {
        
if (ch[now][
0]&&
size[ch[now][
0]]>=x) now=ch[now][
0];
        
else
        {
            
if (ch[now][
0]) x-=
size[ch[now][
0]];
            
if (x==
1) 
return now;
            --x;
            now=ch[now][
1];
        }
    }
}
int main()
{
    scanf(
"%d%d",&n,&m);
    
for (
int i=
1;i<=n;++i) scanf(
"%d",&a[i+
1]);
    root=build(
1,n+
2,
0);sz=n+
2;
    
while (m--)
    {
        scanf(
"%s",opt);
        
if (opt[
0]==
'm'&&opt[
1]==
'e')
        {
            
int x,e;scanf(
"%d%d",&x,&e);
            
            
int aa=find(x);
            
int bb=find(x+
3);
            splay(aa,
0);
            splay(bb,aa);
            
            ch[ch[root][
1]][
0]=
0;
            
            ++sz;
            f[sz]=ch[root][
1];ch[ch[root][
1]][
0]=sz;
            
size[sz]=
1;cha[sz]=inf;
            key[sz]=maxn[sz]=minn[sz]=
ls[sz]=rs[sz]=e;
            update(ch[root][
1]);
            update(root);
        }
        
else if (opt[
0]==
'i')
        {
            
int x,e;scanf(
"%d%d",&x,&e);
            
            
int aa=find(x+
1);
            
int bb=find(x+
2);
            splay(aa,
0);
            splay(bb,aa);
            
            ++sz;
            
size[sz]=
1;cha[sz]=inf;
            f[sz]=ch[root][
1];ch[ch[root][
1]][
0]=sz;
            key[sz]=maxn[sz]=minn[sz]=
ls[sz]=rs[sz]=e;
            update(ch[root][
1]);
            update(root);
        }
        
else if (opt[
0]==
'm'&&opt[
1]==
'a')
        {
            
int x,y;scanf(
"%d%d",&x,&y);
            
            
int aa=find(x);
            
int bb=find(y+
2);
            splay(aa,
0);
            splay(bb,aa);
            
            
int now=ch[ch[root][
1]][
0];
            printf(
"%d\n",maxn[now]-minn[now]);
        }
        
else
        {
            
int x,y;scanf(
"%d%d",&x,&y);
            
            
int aa=find(x);
            
int bb=find(y+
2);
            splay(aa,
0);
            splay(bb,aa);
            
            
int now=ch[ch[root][
1]][
0];
            printf(
"%d\n",cha[now]);
        }
    }
}