uva3143Fast Matrix Operations(线段树)

来源:互联网 发布:中南大学教务网络 编辑:程序博客网 时间:2024/05/16 15:06

刘汝佳数据结构专场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);elseto(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 stubnew FastMatrix().run();}}


原创粉丝点击