uva3143Fast Matrix Operations(线段树)

原创 2012年03月30日 16:05:26

刘汝佳数据结构专场F题,点击打开题目链接

在一个矩阵内完成以下操作:

1.将某子矩阵的值全部加v

2.将某子矩阵的值全部变为v

3.输出某子矩阵的最大值最小值及总和。

由于矩阵至多只有20行,因此可以维护20棵线段树。维护变化统计量时要考虑多种次序,例如未更新的节点先加后边和先边后加,变化的优先级应高于加。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;

public class FastMatrix {
	class SegTree {
		class node {
			int left, right;
			int val, add;
			boolean flag;
			int sum, max, min;

			final int mid() {
				return (left + right) >> 1;
			}

			final int length() {
				return right - left + 1;
			}

			final void init(int k) {
				sum = length() * k;
				max = min = k;
			}

			final void add(int k) {
				min += k;
				max += k;
				sum += length() * k;
			}
		}

		node tree[];
		SegTree(int maxn) {
			tree = new node[maxn * 3];
		}

		final void init(int left, int right, int idx) {
			tree[idx] = new node();
			tree[idx].left = left;
			tree[idx].right = right;
			if (left == right)
				return;
			int mid = tree[idx].mid();
			init(left, mid, idx << 1);
			init(mid + 1, right, (idx << 1) | 1);
		}

		final int[] query(int left, int right, int idx) {
			pushdown(idx);
			int ans[] = new int[3];
			if (tree[idx].left == left && tree[idx].right == right) {
				ans[0] = tree[idx].sum;
				ans[1] = tree[idx].min;
				ans[2] = tree[idx].max;
				return ans;
			}
			int mid = tree[idx].mid();
			if (right <= mid)
				return query(left, right, idx << 1);
			else if (left > mid)
				return query(left, right, (idx << 1) | 1);
			else {
				int ans1[] = query(left, mid, idx << 1);
				int ans2[] = query(mid + 1, right, (idx << 1) | 1);
				ans[0] = ans1[0] + ans2[0];
				ans[1] = Math.min(ans1[1], ans2[1]);
				ans[2] = Math.max(ans1[2], ans2[2]);
				return ans;
			}
		}

		final void update(int left, int right, int idx, int op, int v) {
			// It's a sub-interval, update it here.
			pushdown(idx);
			if (left <= tree[idx].left && right >= tree[idx].right) {
				if (op == 1)
					by(idx, v);
				else
					to(idx, v);
				return;
			}
			int mid = tree[idx].mid();
			if (left <= mid)
				update(left, right, idx << 1, op, v);
			if (mid < right)
				update(left, right, (idx << 1) | 1, op, v);
			pushup(idx);
		}

		final void pushup(int idx) {
			if (tree[idx].left == tree[idx].right)
				return;
			pushdown(idx << 1);
			pushdown((idx << 1) | 1);
			tree[idx].sum = tree[idx << 1].sum + tree[(idx << 1) | 1].sum;
			tree[idx].max = Math.max(tree[idx << 1].max,
					tree[(idx << 1) | 1].max);
			tree[idx].min = Math.min(tree[idx << 1].min,
					tree[(idx << 1) | 1].min);
		}

		final void pushdown(int idx) {
			int v = tree[idx].val;
			boolean temp = tree[idx].flag;
			int a = tree[idx].add;
			if (temp || a != 0) {
				if (tree[idx].flag)
					tree[idx].init(v);
				if (a != 0)
					tree[idx].add(a);
				tree[idx].flag = false;
				tree[idx].add = 0;
				if (tree[idx].left != tree[idx].right) {
					int t = idx << 1;
					if (temp)
						to(t, v);
					by(t, a);
					t++;
					if (temp)
						to(t, v);
					by(t, a);
				}
			}
		}

		final void by(int idx, int k) {
			tree[idx].add += k;
		}

		final void to(int idx, int k) {
			tree[idx].flag = true;
			tree[idx].val = k;
			tree[idx].add = 0;
		}
	}

	StreamTokenizer in = new StreamTokenizer(new BufferedReader(
			new InputStreamReader(System.in)));

	int next() throws IOException {
		in.nextToken();
		return (int) in.nval;
	}

	SegTree st[] = new SegTree[21];

	void run() throws IOException {
		for (int i = 1; i <= 20; i++)
			st[i] = new SegTree(100010);
		while (in.nextToken() != in.TT_EOF) {
			int r = (int) in.nval;
			int c = next();
			int m = next();
			for (int i = 1; i <= r; i++) {
				st[i].init(1, c, 1);
			}
			while (m-- > 0) {
				int op = next();
				int ax = next();
				int ay = next();
				int bx = next();
				int by = next();
				if (op == 1 || op == 2) {
					int v = next();
					for (int i = ax; i <= bx; i++)
						st[i].update(ay, by, 1, op, v);
				} else {
					int sum = 0;
					int max = -1999999999;
					int min = 1999999999;
					for (int i = ax; i <= bx; i++) {
						int ans[] = st[i].query(ay, by, 1);
						sum += ans[0];
						min = Math.min(min, ans[1]);
						max = Math.max(max, ans[2]);
					}
					System.out.println(sum + " " + min + " " + max);
				}
			}
		}
	}

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		new FastMatrix().run();
	}

}


版权声明:本文为博主原创文章,未经博主允许不得转载。

11992 - Fast Matrix Operations (线段树)

题目链接:点击打开链接 该题是线段树的区间更新和区间求和操作, 但是注意区间更新的时候有两个操作:修改值和增加值 。    这两个操作在某些情况下会相互影响 。 细节参见代码: #inclu...
  • weizhuwyzc000
  • weizhuwyzc000
  • 2015年09月26日 09:50
  • 403

UVA11992:Fast Matrix Operations(线段树)

题意: 有一个初始状态全为0的矩阵,一共有三个操作 1 x1 y1 x2 y2 v:子矩阵(x1,y1,x2,y2)所有元素增加v 2 x1 y1 x2 y2 v:子矩阵(x1,y1,x2,y2...
  • libin56842
  • libin56842
  • 2015年06月14日 10:58
  • 1010

UVa11992 - Fast Matrix Operations(线段树)

题目链接简介: 给出一个矩阵,支持以下操作: 子矩阵加,子矩阵赋值,子矩阵查询元素和,最大值和最小值分析: 矩阵不超过20行 所以我们可以每一行都建一棵线段树,这样就转换成了一维问题set和a...
  • wu_tongtong
  • wu_tongtong
  • 2017年10月23日 11:17
  • 53

uva11992 Fast Matrix Operations (线段树)

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18697 题意:给定N*M的矩阵,初始值为0。有三种操作①将x1~x2行...
  • w20810
  • w20810
  • 2015年07月13日 13:53
  • 270

UVA11992 Fast Matrix Operations(线段树)

题目链接:点击链接题意:给一个矩阵,有三个操作。操作1,将这个矩阵的一个子矩阵的值全加上v。操作2,将这个矩阵的一个子矩阵的值全置为v。操作3,求这个矩阵的一个子矩阵的最大值,最小值,和。思路:看似很...
  • qq_33279781
  • qq_33279781
  • 2017年08月23日 16:03
  • 87

UVA 11992 - Fast Matrix Operations(线段树)

UVA 11992 - Fast Matrix Operations 题目链接 题意:给定一个矩阵,3种操作,在一个矩阵中添加值a,设置值a,查询和 思路:由于最多20列,所以完全可以当作20个...
  • u011217342
  • u011217342
  • 2014年07月30日 03:28
  • 1207

LA-11992-Fast Matrix Operations 快速矩阵操作(线段树成段更新)

题意: 给定一个r*c(r 1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1 2 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1 ...
  • viphong
  • viphong
  • 2015年09月06日 18:19
  • 409

uva 11992 Fast Matrix Operations 线段树

代码:
  • a601025382s
  • a601025382s
  • 2014年08月03日 11:31
  • 1289

uva 11992 - Fast Matrix Operations(线段树)

题目链接:uva 11992 - Fast Matrix Operations 题目大意:给定一个R∗C的矩阵,初始状态每个位置均为0, 然后进行Q次操作 1,x1,y1,x2,y...
  • u011328934
  • u011328934
  • 2014年08月25日 11:42
  • 970

UVA - 11992 Fast Matrix Operations(线段树)

对于一个r*c的矩阵
  • u014435976
  • u014435976
  • 2014年11月22日 10:37
  • 434
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:uva3143Fast Matrix Operations(线段树)
举报原因:
原因补充:

(最多只允许输入30个字)