• 2019牛客多校A All-one Matrices——单调栈


    题目

    求非嵌套子矩阵的个数。

    分析

    单调栈的套路题(类似的有求最大子矩阵)。

    首先,按列预处理,每个位置化成连续1的个数。

    例如,左边的图转成右边。

                        

    然后枚举每一行作为矩阵的底边,再从前往后枚举每一列,并维护一个关于高度的单调上升的栈。对于栈中每一个Up值,还需要维护一个其向左能拓展的最远位置Left(其实这个很容易实现,只需用一个普通的栈并与单调栈同步,同入同出)。

    那么每当有元素退栈时,设退栈元素为 (Up, Left),那么可以得到一个全1矩阵 (i-Up+1, Left) - (i, j)。

    还需要判断这个矩阵能否会被更大的矩形嵌套,随便用一种方法判断一下。例如,用 C[left] [right] 表示以 left-right 为宽的矩形延伸到了哪一行。

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int maxn = 3000 + 10;
    int n, m, A[maxn][maxn], B[maxn][maxn], C[maxn][maxn];
    char s[maxn];
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 0;i < n;i++)
        {
            scanf("%s", s);
            for(int j = 0;j < m;j++)  A[i+1][j+1] = s[j] - '0';
        }
        for(int j = 1;j <= m;j++)
            for(int i = 1;i <= n;i++)
            {
                if(A[i][j] == 1)  B[i][j] = B[i-1][j] + 1;
                else B[i][j] = 0;
            }
    
        ll ans = 0;
        memset(C, -1, sizeof(C));
        for(int i = 1;i <= n;i++)
        {
            stack<int>st1, st2;
            for(int j = 1;j <= m+1;j++)
            {
                int left = j;
                while(!st1.empty() && B[i][j] < st1.top())
                {
                    if(C[st2.top()][j] != i - 1)  ans++;    //与上一层不是同一个最大矩形时
                    C[st2.top()][j] = i;
                    st1.pop();
                    left = st2.top();
                    st2.pop();
                }
    
                if((st1.empty() && B[i][j] != 0) || (!st1.empty() && B[i][j] > st1.top()))
                {
                    st1.push(B[i][j]);
                    st2.push(left);
                }
            }
        }
        printf("%lld
    ", ans);
        return 0;
    }

    参考链接: https://blog.csdn.net/zuzhiang/article/details/78693421

  • 相关阅读:
    Teamwork[HDU4494]
    The Parallel Challenge Ballgame[HDU1101]
    「JSOI2016」无界单词
    「SCOI2015」小凸玩密室
    #3636. IIIDX(iiidx)
    #2652. 背单词(word)
    「JXOI2017」加法
    拙者
    19.10.01 acm E:Lowest Common Ancestor
    #3391. big
  • 原文地址:https://www.cnblogs.com/lfri/p/11333434.html
Copyright © 2020-2023  润新知