Gym - 101102D Rectangles (单调栈)
Given an R×C grid with each cell containing an integer, find the number of subrectangles in this grid that contain only one distinct integer; this means every cell in a subrectangle contains the same integer.
A subrectangle is defined by two cells: the top left cell (r1, c1), and the bottom-right cell (r2, c2) (1 ≤ r1 ≤ r2 ≤ R) (1 ≤ c1 ≤ c2 ≤ C), assuming that rows are numbered from top to bottom and columns are numbered from left to right.
Input
The first line of input contains a single integer T, the number of test cases.
The first line of each test case contains two integers R and C (1 ≤ R, C ≤ 1000), the number of rows and the number of columns of the grid, respectively.
Each of the next R lines contains C integers between 1 and 109, representing the values in the row.
Output
For each test case, print the answer on a single line.
Example
1
3 3
3 3 1
3 3 1
2 2 5
16
题意:问由单一数字组成的矩阵的个数。
思路:
dp[i][j]表示以位置i,j为右下角的矩阵个数。
先处理出当前位置向上延伸相同的数字最高有多高。用num[i]记录。
用单调栈处理出在此之前的,第一个小于自己的num[i].
判断中间有没有插入别的数,再进行处理。详见solve函数。
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 #include<stack> 5 #include<queue> 6 #include<map> 7 #include<set> 8 #include<cstdio> 9 #include<cstring> 10 #include<cmath> 11 #include<ctime> 12 #define fuck(x) cout<<#x<<" = "<<x<<endl; 13 #define debug(a,i) cout<<#a<<"["<<i<<"] = "<<a[i]<<endl; 14 #define ls (t<<1) 15 #define rs ((t<<1)|1) 16 using namespace std; 17 typedef long long ll; 18 typedef unsigned long long ull; 19 const int maxn = 1024; 20 const int maxm = 100086; 21 const int inf = 2.1e9; 22 const ll Inf = 999999999999999999; 23 const int mod = 1000000007; 24 const double eps = 1e-6; 25 const double pi = acos(-1); 26 int n,m; 27 int mp[maxn][maxn]; 28 int num[maxn]; 29 ll ans; 30 struct node{ 31 int num,pos; 32 }; 33 stack<node>st; 34 int pre[maxn]; 35 int pre1[maxn]; 36 ll dp[maxn]; 37 void solve(int t){ 38 memset(dp,0,sizeof(dp)); 39 memset(pre,0,sizeof(pre)); 40 while(!st.empty()){ 41 st.pop(); 42 } 43 num[0]=-1; 44 for(int i=m;i>=0;i--){ 45 while(!st.empty()&&st.top().num>num[i]){ 46 pre[st.top().pos]=i; 47 st.pop(); 48 } 49 st.push(node{num[i],i}); 50 } 51 int k=1; 52 for(int i=1;i<=m;i++){ 53 if(mp[t][i]!=mp[t][i-1]){ 54 k=i; 55 } 56 pre1[i]=k; 57 } 58 int pree; 59 for(int i=1;i<=m;i++){ 60 if(pre1[i]>pre[i]){ 61 dp[i]=1ll*num[i]*(i-pre1[i]+1); 62 ans+=dp[i]; 63 } 64 else{ 65 dp[i]=1ll*num[i]*(i-pre[i])+dp[pre[i]]; 66 ans+=dp[i]; 67 } 68 } 69 } 70 71 int main() 72 { 73 int T; 74 scanf("%d",&T); 75 while(T--){ 76 scanf("%d%d",&n,&m); 77 for(int i=1;i<=n;i++){ 78 for(int j=1;j<=m;j++){ 79 scanf("%d",&mp[i][j]); 80 } 81 } 82 ans=0; 83 memset(num,0,sizeof(num)); 84 for(int i=1;i<=n;i++){ 85 for(int j=1;j<=m;j++){ 86 if(mp[i][j]==mp[i-1][j]){ 87 num[j]++; 88 } 89 else{ 90 num[j]=1; 91 } 92 } 93 solve(i); 94 } 95 printf("%lld\n",ans); 96 } 97 return 0; 98 }
如有侵权,联系删除
2290713181@qq.com