Description
You are given a number matrix A with N rows and M columns. Elements in the matrix are referred as Ai,j where 0 ≤ i < N and 0 ≤ j < M. The matrix has the following two properties:
l For each row, the numbers increase from left to right, that is Ai,j-1 ≤ Ai,j for all 0 ≤ i < N and 1 ≤ j < M
l For each column, the numbers increase from top to bottom, that is Ai-1,j ≤ Ai,j for all 1 ≤ i < N and 0 ≤ j < M
You are expected to answer some queries like “whether number p exists in A[lx, rx; ly, ry] and what’s its position?” Here p, lx,rx, ly and ry are given parameters, and A[lx, rx; ly, ry] is a sub-matrix of A formed by rows lx, lx+1, …, rx and columns ly, ly+1, …, ry.
Moreover, there may be some modification instructions between queries, in the form of “increase all numbers in row x by delta”. The matrix after each modification is guaranteed to satisfy the previous two properties.
Input
On the first line of input, there is a single positive integer T ≤ 10 specifying the number of test cases to follow.
For each test case, there are three positive integers N, M, Q in the first line (N, M ≤ 1000, Q ≤ 5000). Next follow N lines, each with M integers, describing the matrix A. Numbers in the matrix are non-negative integers smaller than 109.
The last part of each test case contains Q lines. Each line would either be “Q p lx rx ly r”, describing a query, or “M x delta” specifying a modification instruction. (0 ≤ lx ≤ rx < N, 0 ≤ ly ≤ ry < M, 0 ≤ x < N, 0 ≤ delta < 32768)
Numbers are separated by spaces.
Output
For each test case you should output the answer to each query, containing two integers x y, the position of p in the matrix.
In case p isn’t in the specified sub-matrix, both x and y should be equal to -1.
In case there’s more than one p in the sub-matrix, output the one with smaller x-coordinate and smaller y-coordinate when x tie.
Sample Input
Copy sample input to clipboard
1
4 4 4
2 3 9 12
4 5 14 15
8 13 16 20
11 21 22 23
Q 13 0 3 0 3
Q 12 1 3 1 3
M 0 1
Q 13 0 3 0 3
Sample Output
2 1
-1 -1
0 3
Problem Source: 庆五一,迎省赛——gdcpc2010
这个题我当时在赛场上没做出来,后来问的别人。看了代码才明白。
这个遍历方式挺巧,我自己想估计想不出来,在此记录一下。
分析:
1. 对于查找操作:从左下角开始遍历,如果该数大于目标,则行减少,如果该数小于目标,则列增加。右上角也可,略。
因为这个矩阵满足从上到下递增,从左到右递增。
所以矩阵的右下角的数为该矩阵的最大数,左上角为最小数,并且对于每一个子矩阵都满足这个条件。
对于每个需要查找的数,以它为中心将该矩阵划分为四块:左上角,右上角,左下角,右下角。
小于该数的数只有可能出现在:左上角,右上角,左下角
大于该数的数只有可能出现在:左下角,右上角,右下角
故可以从其左下端点或者右上端点开始遍历。
以左下端点为例:
如果它比目标小,那么想要接近目标,只有列增加。
因为只有右下角一定比目标大,所以它想要接近目标,只有向右下角移动。又因为其处于左下角,所以只需要增加列。
如果它比目标大,那么想要接近目标,只有行减少。
只有左上角一定比目标小,所以它想要接近目标,只有向左上角移动,又因为其处于左下角,所以只需要减少行。
2. 对于增加操作:因为每次是固定增加一行,因此只需要每行设置一个标记,标记该行累加了多少,判断的时候,加上这个累加量即可。