60pts线段树求调
查看原帖
60pts线段树求调
836138
lzg_070506楼主2023/11/16 16:42
//思路:维护线段树节点的左右端点下标实现删除操作
//对于要删除的节点,将该节点的最大值设为最小,最小值设为最大 
#include<bits/stdc++.h>
using namespace std;
int n,m,opt,s,e;
struct V{
	int l,r;
	int left;
	int ma,mi;
}a[2097152];

void up(int u){
	int ls=(u<<1),rs=(u<<1|1);
	a[u].ma=max(a[ls].ma,a[rs].ma);
	a[u].mi=min(a[ls].mi,a[rs].mi);
}

void down(int u){
	int ls=(u<<1),rs=(u<<1)|1;
	a[ls].l-=a[u].left;a[ls].r-=a[u].left;
	a[rs].l-=a[u].left;a[rs].r-=a[u].left;
	a[ls].left+=a[u].left;
	a[rs].left+=a[u].left;
	a[u].left=0;
}

void init(int u,int l,int r){
	a[u].l=l;a[u].r=r;
	if(l==r){
		scanf("%d",&a[u].ma);
		a[u].mi=a[u].ma;
		return;
	}
	int mid=(l+r)>>1;
	init(u<<1,l,mid);init((u<<1)|1,mid+1,r);
	up(u);
	return;
}

void de(int u){
	int l=a[u].l,r=a[u].r;
	if(l>s){
		a[u].left++;
		a[u].l--;
		a[u].r--;
		return;
	}
	if(l==s && r==s){
		a[u].ma=-2e9-7;
		a[u].mi=2e9+7;
		return;
	}
	down(u);
	int mid=a[u<<1].r;
	a[u].r--;
	de((u<<1)|1);
	if(s<=mid) de(u<<1);
	up(u);
	return;
}

int qmi(int u){
	int l=a[u].l,r=a[u].r;
	if(s<=l && r<=e){
		return a[u].mi;
	}
	down(u);
	int mid=a[u<<1].r,ba=2e9+7;
	if(s<=mid) ba=min(ba,qmi(u<<1));
	if(e>mid) ba=min(ba,qmi((u<<1)|1));
	return ba;
}

int qma(int u){
	int l=a[u].l,r=a[u].r;
	if(s<=l && r<=e){
		return a[u].ma;
	}
	down(u);
	int mid=a[u<<1].r,ba=-2e9-7;
	if(s<=mid) ba=max(ba,qma(u<<1));
	if(e>mid) ba=max(ba,qma((u<<1)|1));
	return ba;
}

int main(){
	cin>>n>>m;
	init(1,1,n);
	while(m--){
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d",&s);
			de(1);
		}
		else{
			scanf("%d%d",&s,&e);
			cout<<qmi(1)<<" "<<qma(1)<<endl;
		}
	}
	return 0;
}

WA后四个点求调

2023/11/16 16:42
加载中...