Links: https://ac.nowcoder.com/acm/contest/888/A Source: Cattle-off network
Title Description
Gromah and LZR entered the great tomb, the first thing they see is a matrix of size n×mn\times mn×m, and the elements in the matrix are all 0 or 1.
LZR finds a note board saying "An all-one matrix is defined as the matrix whose elements are all 11_{}1, you should determine the number of all-one submatrices of the given matrix that are not completely included by any other all-one submatrices".
Meanwhile, Gromah also finds a password lock, obviously the password should be the number mentioned in the note board!
Please help them determine the password and enter the next level.
Enter a description:
The first line contains two positive integers n,mn,m_{}n,m, denoting the size of given matrix.Following nn_{}n lines each contains a string with length mm_{}m, whose elements are all 00_{}0 or 11_{}1, denoting the given matrix.1≤n,m≤30001\le n,m \le 30001≤n,m≤3000
Output Description:
Print a non-negative integer, denoting the answer.
Example 1
Entry
3 4
0111
1110
0101
Export
5
Explanation
The 5 matrices are (1,2)−(1,4), (1,2)−(2,3), (1,2)−(3,2), (2,1)−(2,3), (3,4)−(3,4).
Thinking
First consider each as \ (1 \) grid under what circumstances would produce answers contribution.
Easy to get: When the lower right corner of the grid is a great all-rectangle 1 contribution will produce the answer.
Therefore, we can enumerate each line as the last line of a great whole rectangle, for each column prefix and seek to maintain a continuous \ (1 \) number.
When enumerating every position, maintaining a strict monotonous stack monotonically increasing and maintaining the position of the left-most reachable.
When the point \ ((i, j) \ ) when the answer generating contributions, \ ((I + 1, J) \) necessarily \ (0 \) , and its height less than 1 (i-1, j) when the height of.
Code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3010;
typedef pair<int,int> pii;
int mp[maxn][maxn], n, m;
int main() {
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j)
scanf("%1d", &mp[i][j]);
}
for (int j=1; j<=m; ++j) {
for (int i=1; i<=n; ++i) {
if(mp[i][j])
mp[i][j] = mp[i-1][j]+1;
}
}
// for (int i=1; i<=n; ++i) {
// for (int j=1; j<=m; ++j)
// printf("%d", mp[i][j]);
// puts("");
// }
int ans = 0;
for (int i=1; i<=n; ++i) {
pii sta[maxn];
int top=0, r=-1;
for (int j=1; j<=m+1; ++j) {
int pos=j;
while(top && sta[top].first > mp[i][j]) {
if(sta[top].second <= r) ++ans;
pos = sta[top--].second;
}
if(!mp[i+1][j]) r = j;
if(mp[i][j] && (!top || sta[top].first<mp[i][j])) sta[++top] = {mp[i][j], pos};
}
}
printf("%d\n", ans);
return 0;
}