uva 11992 Fast Matrix Operations (线段树区间修改,模板题)

e[i]给出第i个点对应的区间范围

s[k][i]给出矩阵第k行的线段树第i个点对应的区间的和

x[k][i]维护最小值

d[k][i]维护最大值

#include <cstdio>
#include <algorithm>
#include <cstring>
#define inf 0x3f3f3f3f
using namespace std;

int s[25][200005*4];
int d[25][200005*4];
int x[25][200005*4];
int add[25][200005*4];
int set[25][200005*4];

struct E{
	int l;
	int r;
};
E e[200005*4];

void build(int l, int r, int o){
	e[o].l = l;
	e[o].r = r;
	if(l == r)	return ;
	int mid = (l+r)/2;
	build(l, mid, o*2);
	build(mid+1, r, o*2+1);
}

void pushdown(int c, int k){
	if(set[k][c] != 0)
	{
		set[k][c*2] = set[k][c*2+1] = set[k][c];
		add[k][c*2] = add[k][c*2+1] = 0;
		x[k][c*2] = x[k][c*2+1] = set[k][c];
		d[k][c*2] = d[k][c*2+1] = set[k][c];
		s[k][c*2] = set[k][c]*(e[c*2].r-e[c*2].l+1);
		s[k][c*2+1] = set[k][c]*(e[c*2+1].r-e[c*2+1].l+1);
		set[k][c] = 0;
	}
	if(add[k][c] != 0)
	{
		add[k][c*2] += add[k][c]; add[k][c*2+1] += add[k][c];
		x[k][c*2] += add[k][c];	  x[k][c*2+1] += add[k][c];
		d[k][c*2] += add[k][c];	  d[k][c*2+1] += add[k][c];
		s[k][c*2] += add[k][c]*(e[c*2].r-e[c*2].l+1);	s[k][c*2+1] += add[k][c]*(e[c*2+1].r-e[c*2+1].l+1);
		add[k][c] = 0;
	}
}

void addt(int o, int k, int l, int r, int addv){
	if(e[o].l == l && e[o].r == r)
	{
		add[k][o] += addv;
		x[k][o] += addv;
		d[k][o] += addv;
		s[k][o] += addv*(r-l+1);
		return ;
	}
	int mid = (e[o].l+e[o].r)/2;                                   
	pushdown(o, k);
	if(r <= mid)
		addt(o*2, k, l, r, addv);
	else
	if(l > mid)
		addt(o*2+1, k, l, r, addv);
	else
	{
		addt(o*2, k, l, mid, addv);
		addt(o*2+1, k, mid+1, r, addv);
	}
	x[k][o] = min(x[k][o*2], x[k][o*2+1]);
	d[k][o] = max(d[k][o*2], d[k][o*2+1]);
	s[k][o] = s[k][o*2] + s[k][o*2+1];
}

void sett(int o, int k, int l, int r, int setv){
	if(l == e[o].l && r == e[o].r)
	{
		add[k][o] = 0;
		set[k][o] = d[k][o] = x[k][o] = setv;
		s[k][o] = (r-l+1)*setv;
		return ;
	}
	pushdown(o, k);
	int mid = (e[o].l+e[o].r)/2;
	if(r <= mid)
		sett(o*2, k, l, r, setv);
	else
	if(l > mid)
		sett(o*2+1, k, l, r, setv);
	else
	{
		sett(o*2, k, l, mid, setv);
		sett(o*2+1, k, mid+1, r, setv);
	}
	x[k][o] = min(x[k][o*2], x[k][o*2+1]);
	d[k][o] = max(d[k][o*2], d[k][o*2+1]);
	s[k][o] = s[k][o*2] + s[k][o*2+1];
}

void query(int o, int k, int l, int r, int& sum, int& maxn, int& minn){
	if(e[o].l == l && e[o].r == r)
	{
		sum = s[k][o];
		maxn = d[k][o];
		minn = x[k][o];
		return ;
	}
	pushdown(o, k);
	int mid = (e[o].l + e[o].r)/2;
	if(r <= mid)
		query(o*2, k, l, r, sum, maxn, minn);
	else
	if(l >= mid+1)
		query(o*2+1, k, l, r, sum, maxn, minn);
	else
	{
		int sum1, sum2, maxn1, maxn2, minn1, minn2;
		query(o*2, k, l, mid, sum1, maxn1, minn1);
		query(o*2+1, k, mid+1, r, sum2, maxn2, minn2);
		sum = sum1+sum2;
		maxn = max(maxn2, maxn1);
		minn = min(minn2, minn1);
	}
	return ;
}
	
int main()
{
	//freopen("ztest.txt","r",stdin);
	//freopen("zans.txt","w",stdout);
	int r, c, n;
	while(scanf("%d%d%d", &r, &c, &n) == 3)
	{
		memset(s, 0, sizeof(s));
		memset(x, 0, sizeof(x));
		memset(d, 0, sizeof(d));
		memset(add, 0, sizeof(add));
		memset(set, 0, sizeof(set));
		build(1, c, 1);
		for(int i = 1; i <= n; i++)
		{
			int a, x1, x2, y1, y2, val;
			scanf("%d", &a);
			if(a == 1)
			{
				scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &val);
				for(int j = x1; j <= x2; j++)
					addt(1, j, y1, y2, val);
			}
			if(a == 2)
			{
				scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &val);
				for(int j = x1; j <= x2; j++)
					sett(1, j, y1, y2, val);
			}
			if(a == 3)
			{
				int sum = 0, minnn = inf, maxnn = -1;
				int sumn, minn, maxn;
				int xiao, da;
				scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
				for(int j = x1; j <= x2; j++)
				{
					query(1, j, y1, y2, sumn, maxn, minn);
					sum += sumn;
					minnn = min(minnn, minn);
					maxnn = max(maxnn, maxn);
				}	
				printf("%d %d %d\n", sum, minnn, maxnn);
			}
		}
	}
	return 0;
}
					
			
			
			
			
			
			
			

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值