题意:不多说了
思路:用单调栈来维护当前点可以围成的高度及长度,注意一些细节
附带一组数据: 3 4
1 2 3 1
1 1 1 1
1 1 1 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=1010;
int A[maxn][maxn],dp[maxn][maxn];
int num[maxn],L[maxn],W[maxn];
int main(){
int T,n,m;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
ll ans=0;
for(int i=1;i<=n;i++){
int k=0;
for(int j=1;j<=m;j++){
scanf("%d",&A[i][j]);
int len=1;
if(A[i][j]==A[i-1][j]) dp[i][j]=dp[i-1][j]+1;
else dp[i][j]=1;
if(A[i][j]!=A[i][j-1]) k=0;
while(W[k]>=dp[i][j]) len+=L[k--];
L[++k]=len;
W[k]=dp[i][j];
num[k]=num[k-1]+len*W[k];
ans+=num[k];
}
}
printf("%I64d\n",ans);
}
return 0;
}