求助,两棵线段树加链表维护,离线把添加变成删除
查看原帖
求助,两棵线段树加链表维护,离线把添加变成删除
189285
水无月黑雪楼主2024/8/29 22:34

两棵线段树,一棵维护原序列,一棵维护排序后的序列,离线把所有添加后的东西生成一个用链表维护的序列,再建树。 然后从后往前扫问题,添加变成删除,然后在线段树上修改为巨大值。但是后两个点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;
}
2024/8/29 22:34
加载中...