Description

Little Bob is a famous builder. He bought land and wants to build a house. Unfortunately, the problem is the

land’s terrain, it has a variable elevation.

The land is shaped like a rectangle, N meters wide and M meters long. It can be divided into N*M squares

(see the image). Bob’s house will be shaped like a rectangle that has sides parallel with the land’s edges and

its vertices coincide with the vertices of the squares. All the land covered by Bob’s house must be of equal

elevation to prevent it from collapsing.

Calculate the number of ways Bob can build his house!

Input

The first line of input contains integers N and M (1 <= N, M <= 1000).

Each of the following N lines contains M integers aij (1 <= aij <= 1000000000), respectively the height of each square of

land.

Warning: Please use faster input methods beacuse the amount of input is very large. (For example, use scanf

instead of cin in C++ or BufferedReader instead of Scanner in Java.)

Output

The first and only line of output must contain the required number from the task statement.

Sample Input


5 3
2 2 2
2 2 1
1 1 1
2 1 2
1 2 1

Sample Output


27

Hint

Clarification of the first example: Some of the possible house locations are rectangles with opposite vertices in (0,0)-

(1,1), (0,0)-(0,2) (height 2) i (2,0)-(2,2), (1,2)-(2,2) (height 1). The first number in the brackets represents the row number

and the second one the column number (0-indexed).

题意:给你一个n*m的矩阵,每一个格子都有自己的价值,让你在矩阵中找一些格子,使得矩形里的格子的价值都相同,问最多能找到的矩形数。

思路:如果是普通暴力的话,那么时间复杂度为O(n*m*m)爆了,所以要找其他方法。我们可以用单调队列做(单调栈也可以做的,其实它们两者的本质是一样的),这题所要维护的东西和之前求一个平面内的最大矩形面积不同,这里求的是最多的矩形个数,我们可以先把二维矩阵转化为一维,即对于每一行的格子,把上面和它价值相同的格子数作为它的高度。那么这个问题就转化成了有许多长方形格子放在地上,让你找到包含矩形底的矩形总个数。用单调队列的时候要维护三个值,q[][0]表示高度,q[][1]表示以它为右下角格子的矩形个数,q[][2]表示坐标,维护一个严格递增单调队列就行了。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 1005
int gra[maxn][maxn],a[maxn][maxn];
int q[1111111][3]; int main()
{
int n,m,i,j;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%d",&gra[i][j]);
a[i][j]=1;
if(i>1 && gra[i][j]==gra[i-1][j]){
a[i][j]+=a[i-1][j];
}
}
}
ll cnt=0;
int front,rear,qidian;
for(i=1;i<=n;i++){
gra[i][0]=-1;
for(j=1;j<=m;j++){
if(gra[i][j]==gra[i][j-1]){
while(front<=rear && q[rear][0]>=a[i][j]){
rear--;
}
rear++;
q[rear][0]=a[i][j];q[rear][2]=j;
if(rear==1){
q[rear][1]=a[i][j]*(j-qidian); //这里相当于底*高
}
else{
q[rear][1]=a[i][j]*(j-q[rear-1][2])+q[rear-1][1] ; //这里要加上队列里前一个高度比它低的矩形算出来的符合要求的矩形
}
cnt+=q[rear][1];
}
else{
front=1;rear=1;
qidian=j-1;
q[rear][0]=a[i][j];
q[rear][1]=a[i][j];
q[rear][2]=j;
cnt+=a[i][j];
}
}
}
printf("%lld\n",cnt);
}
return 0;
}

最新文章

  1. js获取url地址中的参数
  2. HTTP深入浅出 http请求
  3. 用Jquery控制文本框只能输入数字和字母
  4. [AFUI]App Framework Quickstart
  5. Win+R指令(1)
  6. ajax发送异步请求
  7. sqlserver的四种分页方式
  8. 修改mysql密码的四种方法
  9. if条件、while循环、for循环 相关练习
  10. 现代Java进阶之路必备技能——2019 版
  11. 算法笔记-exgcd
  12. 新浪广告交易平台(SAX)DSP手册
  13. 自己封装framworks上传到应用商店报错
  14. java多线程--------深入分析 ThreadLocal 内存泄漏问题
  15. 一些关于VC++开发的笔记
  16. MySQL FEDERATED 存储引擎的使用
  17. ios7适配--navgationbar遮住下面view的处理
  18. junit4单元測试总结
  19. Installing Redis more properly
  20. EntityFramework 学习 一 Persistence in Entity Framework

热门文章

  1. TCP/IP五层模型-传输层-UDP协议
  2. 在 Azure 上执行一些简单的 python 工作
  3. P1341 无序字母对(欧拉回路)
  4. EntityFramework Core如何映射动态模型?
  5. uni-app开发经验分享十: 封装request请求
  6. Amazon Selling Partner API 开发笔记
  7. 《awk中文手册》-本人参考官方手册翻译
  8. vue首次加载白屏过渡动画(vue优化)
  9. GStreamer环境搭建篇
  10. 抽取一部分服务端做BFF(Backend For Frontend服务于前端的后端)