Codeforces 372b. Counting rectangles is fun [Dynamic Planning, brute force enumeration] (lowbit () Small usage)

Source: Internet
Author: User
A matrix consisting of 0 and 1 is given, asking how many rectangles (A, B) To (c, d) contain only 0 between the two vertices.
Method: Since the matrix is not large, a maximum of 40*40, and a large number of queries (10 ^ 5), we consider O (1) Output answer. First, we use a four-dimensional array to pre-process the answer, finally, output directly. Set DP [a] [B] [C] [d] to the number of rectangles with only 0 between (A, B) and (C, D, the recursive formula: DP [a] [B] [C] [d] = DP [a] [B] [C] [D-1] + dp [a] [B] [C-1] [d ]-DP [a] [B] [C-1] [D-1]

You can add a rectangle containing the vertex (c, d) to each calculation. To calculate the rectangle containing the vertex (c, d), we need to know the distance between each vertex and the nearest one or boundary in each row, so we use an array row [I] [J] to record the distance between (I, j) and the nearest 1 or boundary when entering the rectangle. For details, see the code and comments.
There are other ways to calculate the distance from each vertex to the nearest 1 or boundary. Of course, I heard from Daniel ..
First, we record the first occurrence of each row in the vector. Each time we look for it, we find the nearest 1 or boundary in the second part of the vector. In this case, the complexity of our algorithm is a logn in the previous complexity. Of course, the maximum n here is 40, which can be ignored.
Type 2: We can save the string 01010 entered in each line as a number to find the distance mentioned above, we need to know the distance from row A to row C to the nearest 1 or boundary of column D. In this way, when traversing Row E (A <e <C ), Shift D to the rightIn this way, you only need to find The number is the number of the first digit from the right to the left.(If the value is 0, it indicates that column D is not 1). If the value is W D-W is the distance required above..
But the question is, how can we find the number of the first 1 digit from right to left? If you Tree ArrayIf you are familiar with it, you will surely think of the lowbit (I) function in it. The actual meaning of this function is unknown and you still cannot remember it. lowbit (I) = I & (-I ), In fact, the value returned by this function is the value of the first 1 from the right to the left of the I value.. Assume that the binary value of I is 11010100, then the-I complement code is 00101100 (Anti-Addition 1). When two numbers are bitwise AND computed, you will find such a magical fact! That is, the result is 00000100.! Isn't that exactly what we want? Although it cannot be used directly, we can get what we want with a little processing. (D-W)Now! Finally, we can get an array so that we can get the number of 1 in a second power in O (1) (for example, the first 100, bit [100] = bit [4] = 2, bit makes the required array), where N is equal to 40 at the maximum. The power of 2 is huge, so it cannot be directly thrown into the Array (otherwise, how large is the memory ?...), But think about it, we actually only need 40 numbers, and we don't need to use every element in the bit array. Yes! Discretization!Modulo the number of quadratic power (the number of Modulo operations can be 9999997,9997, as long as 40 modulo results are not the same ~~), In a hash, we can implement the above functions ~~

I have to say that this method is really a bit amazing ~ Ym ..~

Code:
# Include <iostream> # include <cstdio> # define n 41 using namespace STD; int row [N] [N], a [n] [N], DP [N] [N] [N] [N]; int main () {int n, m, Q; scanf ("% d", & N, & M, & Q); For (INT I = 1; I <= N; I ++) for (Int J = 1; j <= m; j ++) {scanf ("% 1D", & A [I] [J]); row [I] [J] = row [I] [J-1]; // when changing rows, row [I] [J] is automatically set to 0; if (a [I] [J]) Row [I] [J] = 0; // when 1 is encountered, set it to 0 else row [I] [J] ++;} For (int A = 1; A <= N; A ++) for (INT B = 1; B <= m; B ++) for (INT c = A; C <= N; C ++) for (INT d = B; D <= m; d ++) {DP [a] [B] [C] [d] = DP [a] [B] [C] [D-1] + dp [a] [B] [C-1] [d]-DP [a] [B] [C-1] [D-1]; int r = D-B + 1; // calculate the rectangle containing the vertex (c, d). Of course, the size cannot exceed the maximum width for (int e = C; e> = A; e --) {r = min (R, row [E] [d]); DP [a] [B] [C] [d] + = r ;}} while (Q --) {int A, B, C, D; scanf ("% d", & A, & B, & C, & D ); cout <DP [a] [B] [C] [d] <Endl;} return 0 ;}


Codeforces 372b. Counting rectangles is fun [Dynamic Planning, brute force enumeration] (lowbit () Small usage)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.