两棵线段树,一棵维护原序列,一棵维护排序后的序列,离线把所有添加后的东西生成一个用链表维护的序列,再建树。 然后从后往前扫问题,添加变成删除,然后在线段树上修改为巨大值。但是后两个点MLE了,求大佬帮忙看看能不能优化。
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m,cnt,lzc;
struct cz{
int typ;
int x;
};
cz q[500006];
struct lb{
int aw;
int nxt;
int num;
long long s;
};
bool cmp(lb ax,lb ay){
return ax.s<ay.s;
}
int h[500006];
lb c[1000006];
lb d[1000006];
int f[1000006];
long long t1[2000006];
long long t2[2000006];
long long ans[500006];
long long a[1000006];
long long b[1000006];
char st[200];
long long minn(long long ax,long long ay){
if(ax<=ay) return ax;
return ay;
}
long long abss(long long ax){
if(ax<0) return ax*-1;
return ax;
}
void update1(int k){
t1[k]=minn(t1[k<<1],t1[k<<1|1]);
}
void update2(int k){
t2[k]=minn(t2[k<<1],t2[k<<1|1]);
}
void build(int k,int l,int r){
if(l==r){
t1[k]=abss(a[l+1]-a[l]);
t2[k]=abss(b[l+1]-b[l]);
}else{
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
update1(k);
update2(k);
}
}
void chg1(int k,int l,int r,int ax,long long ay){
if(l==r&&l==ax){
t1[k]=ay;
return;
}
int mid=l+r>>1;
if(ax<=mid) chg1(k<<1,l,mid,ax,ay);
else chg1(k<<1|1,mid+1,r,ax,ay);
update1(k);
}
void chg2(int k,int l,int r,int ax,long long ay){
if(l==r&&l==ax){
t2[k]=ay;
return;
}
int mid=l+r>>1;
if(ax<=mid) chg2(k<<1,l,mid,ax,ay);
else chg2(k<<1|1,mid+1,r,ax,ay);
update2(k);
}
int main(){
scanf("%d%d",&n,&m);
int i,j,ay;
long long ax;
for(i=1;i<=n;i++){
scanf("%lld",&c[i].s);
if(i!=n) c[i].nxt=i+1;
else c[i].nxt=-1;
if(i!=1) c[i].aw=i-1;
else c[i].aw=-1;
h[i]=i;
}
cnt=n;
for(i=1;i<=m;i++){
scanf("%s",st);
if(st[0]=='I'){
q[i].typ=1;
scanf("%d%lld",&j,&ax);
ay=c[h[j]].nxt;
if(ay!=-1) c[ay].aw=cnt;
c[h[j]].nxt=++cnt;
c[cnt].nxt=ay;
c[cnt].num=i;
c[cnt].s=ax;
c[cnt].aw=h[j];
q[i].x=cnt;
h[j]=cnt;
}else if(st[4]=='S'){
q[i].typ=2;
}else{
q[i].typ=3;
}
}
for(i=1,j=1;i!=-1;i=c[i].nxt,j++){
c[i].num=j;
d[j].s=c[i].s;
d[j].num=j;
}
sort(d+1,d+cnt+1,cmp);
for(i=1;i<=cnt;i++){
f[d[i].num]=i;
if(i!=cnt) d[i].nxt=i+1;
else d[i].nxt=-1;
if(i!=1) d[i].aw=i-1;
else d[i].aw=-1;
}
for(i=1,j=1;i!=-1;i=c[i].nxt,j++) a[j]=c[i].s;
for(i=1,j=1;i!=-1;i=d[i].nxt,j++) b[j]=d[i].s;
build(1,1,cnt-1);
for(i=m;i>=1;i--){
if(q[i].typ==1){
ay=q[i].x;
if(c[ay].nxt!=-1){
chg1(1,1,cnt-1,c[ay].num,1e10);
chg1(1,1,cnt-1,c[c[ay].aw].num,abss(c[c[ay].aw].s-c[c[ay].nxt].s));
c[c[ay].aw].nxt=c[ay].nxt;
c[c[ay].nxt].aw=c[ay].aw;
}else{
chg1(1,1,cnt-1,c[ay].aw,1e10);
}
ay=f[c[q[i].x].num];
if(d[ay].nxt!=-1){
chg2(1,1,cnt-1,ay,1e10);
chg2(1,1,cnt-1,d[ay].aw,abss(d[d[ay].aw].s-d[d[ay].nxt].s));
d[d[ay].aw].nxt=d[ay].nxt;
d[d[ay].nxt].aw=d[ay].aw;
}else{
chg2(1,1,cnt-1,d[ay].aw,1e10);
}
}else if(q[i].typ==2){
ans[++lzc]=t2[1];
}else{
ans[++lzc]=t1[1];
}
}
for(i=lzc;i>=1;i--) printf("%lld\n",ans[i]);
return 0;
}