Description
要求资瓷以下操作
merge x e 合并第x个元素和第x+1个元素,权值变为e
insert x e 在第x个元素和第x+1个元素之间插入一个权值为 e 的新元素。
max x y 当前第 x 到第 y 个元素之间的任意子区间中区间极差的最大值;
min x y 当前第 x 到第 y 个元素子之间的任意子区间中区间极差的最小值。
N<=100,000,M<=100,000
1 ≤ e, Ei ≤ 109。 设 N’ 为当前时刻原子数目。
对于 merge 类事件, 1 ≤ x ≤ N’-1;
对于 insert 类事件, 1 ≤ x ≤ N’;
对于 max 和 min 类事件, 1 ≤ x < y ≤ N’。
任何时刻,保证 N’ ≥ 2。
Solution
动态删除和添加就不能用线段树惹
max询问实质就是找到区间中最大值和最小值的差
min询问实质就是找到区间中相邻元素权值差值的最小值
那么splay维护区间最大值、最小值、相邻差值的最小值即可
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
const int INF=0x3f3f3f3f;
const int N=400005;
struct treeNode {int son[2],fa,size,e,max,min,rec,delta;} t[N];
int e[N],root,tot;
void new_node(int fa,int e,int delta) {
t[++tot]=(treeNode) {{0,0},fa,1,e,e,e,delta,delta};
if (e==INF) {
t[tot].max=-INF;
t[tot].e=0;
t[tot].rec=INF;
}
}
void push_up(int x) {
t[x].max=std:: max(t[t[x].son[0]].max,t[t[x].son[1]].max);
t[x].min=std:: min(t[t[x].son[0]].min,t[t[x].son[1]].min);
if (t[x].e) {
t[x].max=std:: max(t[x].max,t[x].e);
t[x].min=std:: min(t[x].min,t[x].e);
}
t[x].rec=std:: min(abs(t[x].delta),std:: min(t[t[x].son[0]].rec,t[t[x].son[1]].rec));
t[x].size=t[t[x].son[0]].size+t[t[x].son[1]].size+1;
}
void rotate(int x) {
int y=t[x].fa; int z=t[y].fa;
int k=t[y].son[1]==x;
t[z].son[t[z].son[1]==y]=x; t[x].fa=z;
t[y].son[k]=t[x].son[!k]; t[t[x].son[!k]].fa=y;
t[y].fa=x; t[x].son[!k]=y;
push_up(y); push_up(x);
}
void splay(int x,int goal=0) {
while (t[x].fa!=goal) {
int y=t[x].fa; int z=t[y].fa;
if (z!=goal) {
if ((t[z].son[1]==y)^(t[y].son[1]==x)) rotate(x);
else rotate(y);
}
rotate(x);
}
if (!goal) root=x;
}
int kth(int k) {
int x=root;
while (233) {
if (t[t[x].son[0]].size+1==k) return x;
if (t[t[x].son[0]].size>=k) {
x=t[x].son[0];
} else {
k-=t[t[x].son[0]].size+1;
x=t[x].son[1];
}
}
}
int main(void) {
freopen("data.in","r",stdin);
freopen("myp.out","w",stdout);
t[0].max=-INF; t[0].min=t[0].rec=INF;
int n,m; scanf("%d%d",&n,&m);
rep(i,1,n) scanf("%d",&e[i]);
new_node(0,0,0); t[tot].max=-INF; t[tot].min=t[tot].rec=t[tot].delta=INF; root=1;
rep(i,1,n) {
int tx=kth(i);
splay(tx);
new_node(root,e[i],e[i]-e[i-1]);
t[root].son[1]=tot;
splay(tot);
}
splay(kth(n+1));
new_node(root,0,0); t[root].son[1]=tot;
t[tot].max=-INF; t[tot].min=INF;
while (m--) {
char opt[8]; scanf("%s",opt);
int x,y; scanf("%d%d",&x,&y);
if (opt[1]=='e') {
int tx=kth(x+1); splay(tx);
int ty=kth(x+3); splay(ty,tx);
t[tx].delta+=y-t[tx].e;
t[tx].e=y;
t[ty].delta=t[ty].e-t[tx].e;
t[ty].son[0]=0;
push_up(ty); push_up(tx);
} else if (opt[0]=='i') {
int tx=kth(x+1); splay(tx);
int ty=kth(x+2); splay(ty,tx);
new_node(ty,y,y-t[tx].e);
t[ty].son[0]=tot;
t[ty].delta=t[ty].e-t[tot].e;
push_up(ty); push_up(tx);
splay(tot);
} else if (opt[1]=='a') {
int tx=kth(x); splay(tx);
int ty=kth(y+2); splay(ty,tx);
printf("%d\n", t[t[ty].son[0]].max-t[t[ty].son[0]].min);
} else {
int tx=kth(x+1); splay(tx);
int ty=kth(y+2); splay(ty,tx);
printf("%d\n", t[t[ty].son[0]].rec);
}
}
return 0;
}