zoukankan      html  css  js  c++  java
  • 洛谷U4859matrix[单调栈]

    题目描述

    给一个元素均为正整数的矩阵,上升矩阵的定义为矩阵中每行、每列都是严格递增的。

    求给定矩阵中上升子矩阵的数量。

    输入输出格式

    输入格式:

    第一行两个正整数n、m,表示矩阵的行数、列数。

    接下来n行,每行m个正整数表示矩阵中的元素。

    输出格式:

    一个数表示数量。

    输入输出样例

    输入样例#1:
    4 4
    1 2 3 4
    2 3 4 5
    3 4 5 6
    4 5 6 7
    
    输出样例#1:
    100

    出题人的题解是O(n3)
    感觉可以用单调栈做O(n2),果真可以
    和仓鼠那道比较像
    只是需要维护两个tot,一个是只考虑上下单增,另一个tot2同时考虑左右单增,合并时只能用tot2
    如果tot>tot2还要给这个节点再加一个
    //
    //  main.cpp
    //  luoguU4859
    //
    //  Created by Candy on 10/10/16.
    //  Copyright © 2016 Candy. All rights reserved.
    //
    
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int N=355;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x;
    }
    int n,m,a[N][N];// 0<a[i][j]
    struct data{
        int l,h;
    }st[N];
    int top=0,tot[N],tot2[N];
    ll ans=0;
    int main(int argc, const char * argv[]) {
        n=read();m=read();
        memset(a,-1,sizeof(a));
        for(int i=1;i<=n;i++){
            top=0;
            ll cnt=0;
            for(int j=1;j<=m;j++){
                a[i][j]=read();
                if(a[i][j]<=a[i-1][j]) tot[j]=tot2[j]=0;
                tot[j]++;tot2[j]++;
                if(a[i][j]<=a[i][j-1]){top=0;cnt=0;tot2[j]=0;}
                
                data tmp;
                tmp.h=tot2[j];
                if(tot[j]==tot2[j]) tmp.l=1;
                else tmp.l=0;
                while(top&&st[top].h>=tmp.h){
                    tmp.l+=st[top].l;
                    cnt-=st[top].l*st[top].h;
                    top--;
                }
                st[++top]=tmp;
                cnt+=tmp.l*tmp.h;
                if(tot[j]>tot2[j]){
                    cnt+=1*tot[j];
                    st[++top].h=tot[j];
                    st[top].l=1;
                }
                ans+=cnt;
                //printf("h %d %d %d %d
    ",i,j,tot[j],tot2[j]);
                //printf("i %d %d %d %d
    cnt %d
    ",i,j,tmp.l,tmp.h,cnt);
            }
            //printf("ans %d
    ",ans);
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    Nginx初探
    很详细的Nginx配置说明
    linux环境下Apache+Tomcat集群配置
    Apache+Tomcat集群配置
    apache + tomcat 负载均衡分布式集群配置
    js 如何将dom转换为 图片(base64)
    饥荒猪镇物品 代码
    angular2 图片赋值的时候前面自动加 unsafe:xxx 导致图片信息不显示问题
    angular6、7 兼容ie9、10、11
    @angular/cli (angular脚手架) 如何降级
  • 原文地址:https://www.cnblogs.com/candy99/p/5948831.html
Copyright © 2011-2022 走看看