HDU - 4902 Nice boat 线段树维护最大最小值

题意:1操作让区间l~r的值为x 2操作让区间大于x的值为gcd(x,ai)

我们维护区间最大值最小值 当最大值等于最小值时 区间的数都相同 这样可以减少2操作的时间 另外 对于mx[id]<=x的区间我们不必要在更新 也可以剪掉

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
int a[N],ans[N];
int mx[N<<2],mi[N<<2],lazy[N<<2];
#define ls (id<<1)
#define rs (ls|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
void pushup(int id){
	mx[id]=max(mx[ls],mx[rs]);
	mi[id]=min(mi[ls],mi[rs]);
}
void cal(int id,int val){
	mx[id]=mi[id]=val;
	lazy[id]=1;
}
void pushdown(int id){
	if(lazy[id]){
		cal(ls,mx[id]);
		cal(rs,mx[id]);
		lazy[id]=0;
	}
}
void build(int id,int l,int r){
	lazy[id]=0;
	if(l==r){
		mx[id]=mi[id]=a[l];
		return;
	}
	int mid = l+r>>1;
	build(lson);build(rson);
	pushup(id);
}
void update(int id,int l,int r,int L,int R,int op,int val){
	if(op==2&&mx[id]<=val) return; 
	if(L<=l&&R>=r){
		if(op==1){
			cal(id,val);
			return;
		}else{
			if(mx[id]==mi[id]){
				cal(id,__gcd(mx[id],val));
				return;
			}
		}
	}
	pushdown(id);
	int mid = l+r>>1;
	if(L<=mid) update(lson,L,R,op,val);
	if(R>mid) update(rson,L,R,op,val);
	pushup(id);
}
void query(int id,int l,int r){
	if(l==r){
		ans[l]=mx[id];
		return;
	}
	pushdown(id);
	int mid = l+r>>1;
	query(lson);query(rson);
}
int main(){
	int f;
	scanf("%d",&f);
	while(f--){
		int n;
		scanf("%d",&n);
		for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
		build(1,1,n);
		int m;
		scanf("%d",&m);
		for(int i = 1; i <= m; i++){
			int op,l,r,x;
			scanf("%d%d%d%d",&op,&l,&r,&x);
			update(1,1,n,l,r,op,x);
		}
		query(1,1,n);
		for(int i = 1; i <= n; i++) printf("%d ",ans[i]);
		puts("");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43824564/article/details/106280517
今日推荐