社区讨论

小萌新求助

P8862 「KDOI-03」还原数据参与者 5已保存回复 6

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
6 条
当前快照
1 份
快照标识符
@lo7i4loe
此快照首次捕获于
2023/10/27 02:12
2 年前
此快照最后确认于
2023/10/27 02:12
2 年前
查看原帖
CPP
#include<iostream>
#include<cstring>
using namespace std;
const int N=3e5+10;
struct SegmentTree{
	long long minn,add;
	int l,r;
	#define l(p) t[p].l
	#define r(p) t[p].r
	#define minn(p) t[p].minn
	#define add(p) t[p].add 
}t[N];
struct opt{
	int type,l,r;
	long long x;
}q[N];
int a[N],b[N];
void build(int p,int l,int r){
	l(p)=l,r(p)=r;
	if(l==r){
		minn(p)=b[l];
		return ;
	}
	int mid=l+r>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	minn(p)=min(minn(p<<1),minn(p<<1|1));
}
void pushdown(int p){
	if(add(p)){
		add(p<<1)+=add(p);
		add(p<<1|1)+=add(p);
		minn(p<<1)+=add(p);
		minn(p<<1|1)+=add(p);
		add(p)=0;
	}
}
void change_add(int p,int l,int r,long long v){
	if(l<=l(p) && r(p)<=r){
		minn(p)+=v;
		add(p)+=v;
		return ;
	}	
	pushdown(p);
	int mid=l(p)+r(p)>>1;
	if(l<=mid) change_add(p<<1,l,r,v);
	if(r>mid) change_add(p<<1|1,l,r,v);
	minn(p)=min(minn(p<<1),minn(p<<1|1)); 
//	minn(p)=min(minn(p<<1),minn(p<<1|1));
}
long long get_minn(int p,int l,int r){
	if(l<=l(p) && r(p)<=r){
		return minn(p);
	}
	pushdown(p);
	int mid=l(p)+r(p)>>1;
	long long res=4e18+10;
	if(l<=mid) res=min(res,get_minn(p<<1,l,r));
	if(r>mid) res=min(res,get_minn(p<<1|1,l,r));
	return res;
}
long long ans[N];
int main(){
	int T; cin>>T;
	while(T--){
		int n,m; scanf("%d%d",&n,&m);
		memset(a,0,sizeof a);
		memset(b,0,sizeof b); 
//		memset(t,0,sizeof t);
		for(int p=1;p<=300000;++p){
			minn(p)=4e16+10;
			l(p)=r(p)=add(p)=0;
//			t[p].minn=0;
		} 
//		for(int i=1)
		for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
		for(int i=1;i<=m;++i){
			scanf("%d%d%d",&q[i].type,&q[i].l,&q[i].r);
			if(q[i].type==1) scanf("%lld",&q[i].x);
		}
		for(int i=1;i<=n;++i) scanf("%lld",&b[i]);
		build(1,1,n);
		int cnt=0;
		for(int i=m;i>=1;--i){
			if(q[i].type==1) change_add(1,q[i].l,q[i].r,-q[i].x);
			else{
//				cout<<114444;
				ans[++cnt]=get_minn(1,q[i].l,q[i].r);
//				change_add(1,)
			}
		}
		for(int i=cnt;i;--i) printf("%lld\n",ans[i]);
	}
	return 0;
}
离线倒着做操作
2 操作区间查最小输出
1 操作变成减法做

回复

6 条回复,欢迎继续交流。

正在加载回复...