Fast Matrix Operation UVA11992




#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>   
#include <map>
#include <string>  
#include <climits> 
#include <set>
#include <string>    
#include <sstream>
#include <utility>   
#include <ctime>

using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::make_pair;
using std::getline;
using std::greater;
using std::endl;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PAIR;

const int MAXN(111111);
const int SIGMA_SIZE(130);
const int MAXM(110);
const int MAXE(200010);
const int MAXH(18);
const int INFI((INT_MAX-1) >> 2);
const int BASE(131);
const ULL LIM(1000000000000000ull);

struct ELE
{
	int sum, mi, ma, size, flag1, flag2;
};

struct SEGMENT_TREE
{
	ELE table[MAXN << 2];
	inline int l_son(int sour)
	{
		return sour << 1;
	}
	inline int r_son(int sour)
	{
		return (sour << 1)|1;
	}
	static void push_up(ELE &sour, const ELE &op1, const ELE &op2)
	{
		sour.sum = op1.sum+op2.sum;
		sour.mi = op1.mi < op2.mi? op1.mi: op2.mi;
		sour.ma = op1.ma > op2.ma? op1.ma: op2.ma;
	}
	static void push_down(ELE &sour, ELE &op1, ELE &op2)
	{
		if(sour.flag2)
		{
			op1.mi = op1.ma = op2.mi = op2.ma = sour.flag2;
			op1.sum = sour.flag2*op1.size;
			op2.sum = sour.flag2*op2.size;
			op1.flag1 = op2.flag1 = 0;
			op1.flag2 = op2.flag2 = sour.flag2;
			sour.flag2 = 0;
		}
		
		if(sour.flag1)
		{
			op1.mi += sour.flag1;
			op2.mi += sour.flag1;
			op1.ma += sour.flag1;
			op2.ma += sour.flag1;
			op1.sum += sour.flag1*op1.size;
			op2.sum += sour.flag1*op2.size;
			op1.flag1 += sour.flag1;
			op2.flag1 += sour.flag1;
			sour.flag1 = 0;
		}
	}
	void  build_tree(int l, int r, int root)
	{
		table[root].mi = table[root].ma = table[root].sum = 0;
		table[root].flag1 = table[root].flag2 = 0;
		table[root].size = r-l+1;
		if(l == r)
			return;
		int m = (l+r) >> 1;
		build_tree(l, m, l_son(root));
		build_tree(m+1, r, r_son(root));
	}
	void add(int ql, int qr, int value, int l, int r, int root)
	{
		if(ql <= l && qr >= r)
		{
			table[root].mi += value;
			table[root].ma += value;
			table[root].sum += value*table[root].size;
			table[root].flag1 += value;
			return;
		}
		push_down(table[root], table[l_son(root)], table[r_son(root)]);
		int m = (l+r) >> 1;
		if(ql <= m)
			add(ql, qr, value, l, m, l_son(root));
		if(qr > m)
			add(ql, qr, value, m+1, r, r_son(root));
		push_up(table[root], table[l_son(root)], table[r_son(root)]);
	}
	void set_v(int ql, int qr, int value, int l, int r, int root)
	{
		if(ql <= l && qr >= r)
		{
			table[root].mi = table[root].ma = value;
			table[root].sum = value*table[root].size;
			table[root].flag1 = 0;
			table[root].flag2 = value;
			return;
		}
		push_down(table[root], table[l_son(root)], table[r_son(root)]);
		int m = (l+r) >> 1;
		if(ql <= m)
			set_v(ql, qr, value, l, m, l_son(root));
		if(qr > m)
			set_v(ql, qr, value, m+1, r, r_son(root));
		push_up(table[root], table[l_son(root)], table[r_son(root)]);
	}
	
	void query(int ql, int qr, int l, int r, int root, ELE &ans)
	{
		if(ql <= l && qr >= r)
		{
			ans = table[root];
			return;
		}
		push_down(table[root], table[l_son(root)], table[r_son(root)]);
		ELE ans1, ans2;
		int m = (l+r) >> 1;
		if(ql <= m)
		{
			query(ql, qr, l, m, l_son(root), ans1);
			ans = ans1;
		}
		if(qr > m)
		{
			query(ql, qr, m+1, r, r_son(root), ans2);
			if(ql <= m)
				push_up(ans, ans1, ans2);
			else
				ans = ans2;
		}
		push_up(table[root], table[l_son(root)], table[r_son(root)]);
	}
};

SEGMENT_TREE st[21];

int main()
{
	int r, c, m;
	while(~scanf("%d%d%d", &r, &c, &m))
	{
		for(int i = 1; i <= r; ++i)
			st[i].build_tree(1, c, 1);
		int flag, x1, y1, x2, y2, op;
		for(int i = 0; i < m; ++i)
		{
			scanf("%d", &flag);
			if(flag == 1)
			{
				scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &op);
				for(int j = x1; j <= x2; ++j)
					st[j].add(y1, y2, op, 1, c, 1);
			}
			if(flag == 2)
			{
				scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &op);
				for(int j = x1; j <= x2; ++j)
					st[j].set_v(y1, y2, op, 1, c, 1);
			}
			if(flag == 3)
			{
				scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
				ELE ans, ans1, ans2;
				st[x1].query(y1, y2, 1, c, 1, ans);
				for(int j = x1+1; j <= x2; ++j)
				{
					st[j].query(y1, y2, 1, c, 1, ans1);
					ans2 = ans;
					SEGMENT_TREE::push_up(ans, ans1, ans2);
				}
				printf("%d %d %d\n", ans.sum, ans.mi, ans.ma);
			}
		}
	}
	return 0;
}


你可能感兴趣的:(Fast Matrix Operation UVA11992)