uva11992(线段树-区间修改)

线段树区间修改模板

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn = 1000005 << 2;
int sum[maxn], maxv[maxn], minv[maxn], setv[maxn], addv[maxn];
int ansmin, ansmax, row, col;

void PushUp(int u) {
	int L = u * 2, R = u * 2 + 1;
	sum[u] = sum[L] + sum[R];
	minv[u] = min(minv[L] , minv[R]);
	maxv[u] = max(maxv[L] , maxv[R]);
}

void PushDown(int u, int len) {
	int L = u  * 2, R = u * 2 + 1;
	if(setv[u] >= 0) { 
		addv[L] = addv[R] = 0;
		minv[L] = maxv[L] = maxv[R] = minv[R] = setv[u];
		sum[L] =  (len - len / 2) * setv[u];
		sum[R] = (len / 2) * setv[u];
		setv[L] = setv[R] = setv[u];
		setv[u] = -1;
	}

	if(addv[u]) {
		sum[L] += (len - len / 2) * addv[u];
		sum[R] += (len / 2) * addv[u];

		minv[L] += addv[u];
		maxv[L] += addv[u];

		minv[R] += addv[u];
		maxv[R] += addv[u];
		
		addv[L] += addv[u];
		addv[R] += addv[u];
		addv[u] = 0;	
	}
}

void build(int u, int L, int R) {
	if(L == R) {
		sum[u] = minv[u] = maxv[u] = 0;
		return ;	
	}
	int mid = (L + R) / 2;
	build(u * 2,L,mid);
	build(u * 2 + 1,mid+1,R);
	PushUp(u);
}

void set_val(int L, int R, int v, int u, int l, int r) {
	if(L <= l && R >= r) {
		addv[u] = 0;
		minv[u] = maxv[u] = v;
		sum[u] = (r - l + 1) * v;
		setv[u] = v;	
		return ;
	}
	int mid = (l + r) / 2;
	PushDown(u,r-l+1);

	if(L <= mid)  
		set_val(L,R,v,u*2,l,mid);
	if(R > mid)
		set_val(L,R,v,u*2+1,mid+1,r);
	PushUp(u);
}

void update(int L, int R, int add, int u, int l, int r) {
	if(L <= l && R >= r) {
		addv[u] += add;
		sum[u] += (r - l + 1) * add;
		maxv[u] += add;
		minv[u] += add;
		return ;
	}

	PushDown(u,r-l+1);
	int mid = (l + r) / 2;
	if(L <= mid)
		update(L,R,add,u * 2,l,mid);
	if(R > mid)
		update(L,R,add,u * 2 + 1, mid+1,r);
	PushUp(u);
}

int query(int L, int R, int u, int l, int r) {
	if(L <= l && R >= r) {
		ansmin = min(ansmin,minv[u]);
		ansmax = max(ansmax,maxv[u]);
		return sum[u];
	}
	PushDown(u,r-l+1);
	int mid = (l + r) / 2;
	int ans = 0;
	if(L <= mid)
		ans += query(L,R,u*2,l,mid);
	if(R > mid)
		ans += query(L,R,u*2 + 1,mid+1,r);
//	PushUp(u);
	return ans;
}

int main() {
	int m, x1, x2, y1, y2, v, n;
	while(scanf("%d%d%d",&row, &col, &m) == 3) {
		memset(setv,-1,sizeof(setv));
		memset(addv,0,sizeof(addv));
		build(1,1,row*col);
		while(m--) {
			scanf("%d", &n);
			if(n == 1) {
				scanf("%d%d%d%d%d",&x1, &y1, &x2, &y2, &v);
				for(int i = x1; i <= x2; i++)
					update((i-1)*col+y1,(i-1)*col+y2,v,1,1,row*col);
			}
			if(n == 2){ 
				scanf("%d%d%d%d%d",&x1, &y1, &x2, &y2, &v);
				for(int i = x1; i <= x2; i++)
					set_val((i-1)*col+y1,(i-1)*col+y2,v,1,1,row*col);
			}
			if(n == 3) {
				scanf("%d%d%d%d",&x1,&y1, &x2, &y2);
				int ans = 0;
				ansmax = -INF, ansmin = INF;
			for(int i = x1; i <= x2; i++)
				ans += query((i-1)*col+y1,(i-1)*col+y2,1,1,row*col);	
			printf("%d %d %d\n", ans, ansmin, ansmax);
			} 
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值