首页 > 代码库 > [luoguP1169] [ZJOI2007]棋盘制作(单调栈)

[luoguP1169] [ZJOI2007]棋盘制作(单调栈)

传送门

 

和玉蟾宫差不多

——代码

技术分享
 1 #include <cstdio> 2 #include <iostream> 3  4 using namespace std; 5  6 const int MAXN = 2001; 7 int n, m, ans1, ans2, top; 8 int a[MAXN][MAXN][2], s[MAXN], r[MAXN], l[MAXN]; 9 10 inline void work(int k)11 {12     int i, j;13     for(i = 0; i <= 1; i++)14     {15         a[k][0][i] = a[k][m + 1][i] = -1;16         top = 0;17         for(j = 1; j <= m + 1; j++)18         {19             while(top && a[k][s[top]][i] > a[k][j][i]) r[s[top--]] = j;20             s[++top] = j;21         }22         top = 0;23         for(j = m; j >= 0; j--)24         {25             while(top && a[k][s[top]][i] > a[k][j][i]) l[s[top--]] = j;26             s[++top] = j;27         }28         for(j = 1; j <= m; j++)29         {30             ans1 = max(ans1, min(a[k][j][i], r[j] - l[j] - 1) * min(a[k][j][i], r[j] - l[j] - 1));31             ans2 = max(ans2, a[k][j][i] * (r[j] - l[j] - 1));32         }33     }34 }35 36 int main()37 {38     int i, j, x;39     scanf("%d %d", &n, &m);40     for(i = 1; i <= n; i++)41         for(j = 1; j <= m; j++)42         {43             scanf("%d", &x);44             if((i + j) % 2) x ^= 1;45             a[i][j][x] = a[i - 1][j][x] + 1;46         }47     for(i = 1; i <= n; i++) work(i);48     printf("%d\n%d\n", ans1, ans2);49     return 0;50 }
View Code

 

[luoguP1169] [ZJOI2007]棋盘制作(单调栈)