poj2019 (two-dimensional line segment tree)

Click to open the question link


Roughly the meaning of the question: Given an n*n matrix and k queries. Given two numbers x, y in each query, the query asks b*b in the upper left corner of the xth row and the yth column

The difference between the maximum and minimum elements in the matrix.


Idea: The two-dimensional problem is simplified, and the one-dimensional situation can be considered first, that is, the maximum and minimum values ​​of elements in the interval are considered. This can be solved with RMQ, of course,

You can also write a line segment tree. I will directly use the line segment tree as the basis for this question. The main formula is maxval[o]=max(maxval[o*2],maxval[o*2+1]),

Then two-dimensional is relatively one-dimensional, almost one more dimension of the array, parameters, boundaries, etc. are a little more complicated. This will be regarded as your own two-dimensional line segment tree template question~~~


code show as below:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

class Reader {
	static BufferedReader reader;
	static StringTokenizer tokenizer;

	static void init(InputStream input) {
		reader = new BufferedReader(new InputStreamReader(input));
		tokenizer = new StringTokenizer("");
	}

	static String next() throws IOException {
		while (!tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}
}

class Num {
	int max, min;

	public Num(int max, int min) {
		super();
		this.max = max;
		this.min = min;
	}

	public Num() {
		super();
		// TODO Auto-generated constructor stub
	}

}

public class Main {

	/**
	 * @param args
	 */
	static int n, b, k, x, y;
	static int val[][];
	static int max[][], min[][];

	private static void btree1(int o, int l, int r) {
		if (l == r) {
			btree2(o, l, r, 1, 1, n);
			return;
		}
		int mid = (l + r) / 2;
		btree1(o * 2, l, mid);
		btree1(o * 2 + 1, mid + 1, r);
		btree2(o, l, r, 1, 1, n);
	}

	private static int getmax(int a, int b) {
		return a > b ? a : b;
	}

	private static int getmin(int a, int b) {
		return a < b ? a : b;
	}

	private static void btree2(int xo, int xl, int xr, int o, int l, int r) {
		if (l == r) {
			if (xl == xr) {
				max[xo][o] = val[xl][l];
				min[xo][o] = val[xr][l];
			} else {
				max[xo][o] = getmax(max[xo * 2][o], max[xo * 2 + 1][o]);
				min [xo] [o] = getmin (min [xo * 2] [o], min [xo * 2 + 1] [o]);
			}
			return;
		}
		int mid = (l + r) / 2;
		btree2(xo, xl, xr, o * 2, l, mid);
		btree2(xo, xl, xr, o * 2 + 1, mid + 1, r);
		max[xo][o] = getmax(max[xo][o * 2], max[xo][o * 2 + 1]);
		min [xo] [o] = getmin (min [xo] [o * 2], min [xo] [o * 2 + 1]);
	}

	private static Num query1(int o, int l, int r) {
		if ((l >= x) && (r <= x + b - 1))
			return query2(o, l, r, 1, 1, n);
		int mid = (l + r) / 2;
		Num num1, num2;
		num1 = new Num(0, Integer.MAX_VALUE);
		if (mid >= x)
			num1 = query1(o * 2, l, mid);
		if (mid < x + b - 1) {
			num2 = query1(o * 2 + 1, mid + 1, r);
			num1.max = getmax(num1.max, num2.max);
			num1.min = getmin(num1.min, num2.min);
		}
		return num1;
	}

	private static Num query2(int xo, int xl, int xr, int o, int l, int r) {
		if ((l >= y) && (r <= y + b - 1)) {
			return new Num(max[xo][o], min[xo][o]);
		}
		int mid = (l + r) / 2;
		Num num1, num2;
		num1 = new Num(0, Integer.MAX_VALUE);
		if (mid >= y)
			num1 = query2(xo, xl, xr, o * 2, l, mid);
		if (mid < y + b - 1) {
			num2 = query2(xo, xl, xr, o * 2 + 1, mid + 1, r);
			num1.max = getmax(num1.max, num2.max);
			num1.min = getmin(num1.min, num2.min);
		}
		return num1;

	}

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		Reader.init(System.in);
		n = Reader.nextInt();
		b = Reader.nextInt();
		k = Reader.nextInt();
		val = new int[n + 1][n + 1];
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				val[i][j] = Reader.nextInt();
		max = new int[4 * n + 1][4 * n + 1];
		min = new int [4 * n + 1] [4 * n + 1];
		btree1(1, 1, n);
		for (int i = 1; i <= k; i++) {
			x = Reader.nextInt();
			y = Reader.nextInt();
			System.out.println(query1(1, 1, n).max - query1(1, 1, n).min);
		}
	}

}


Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326741638&siteId=291194637