zoukankan      html  css  js  c++  java
  • [LUOGU]P3400 仓鼠窝

    传送门

    首先分析问题,我们要求出所有的子矩形,不妨考虑以每一点为右下角的子矩形的个数,加起来正好就是总的子矩形数了。

    然后考虑每一个点为左下角时的方案数,我们考虑每在它左上的点是否可以作为矩形的左上角。

    如图

    01111

    11011

    10111

    10111

    1111X

    我们考虑以X为子矩形右下角的的方案数,下图中#为可行的左上角

    011##

    110##

    10###

    10###

    我们发现所有的'#'形成一个连通块,并且长度向上单调递减,递减的原因是'0'的限制,所以每一行最右边的'0'可以用一个数组维护,我们现在令第i行最右边的'0'的位置为height[i].

    然后我们可以在扫描每一列时,用一个单调栈维护这个单调壳,并维护每一个位置的答案,每次望栈中添加元素时直接从上一状态转移答案,具体代码如下。似乎比别的题解短了一截。

    P.S. 不用开读如优化,scanf就够用了(我猜cin也行

    记得开long long

    ### copy from 这里 

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define re register
     4 #define LL long long
     5 #define DB double
     6 #define For(x,a,b) for(re int x=a;x<=b;x++)
     7 #define For2(x,a,b) for(re int x=a;x>=b;x--)
     8 #define LFor(x,a,b) for(re LL x=a;x<=b;x++)
     9 #define LFor2(x,a,b) for(re LL x=a;x>=b;x--)
    10 #define Abs(x) ((x>0)? x:-x)
    11 int gi()
    12 {
    13     int res=0,fh=1;char ch=getchar();
    14     while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    15     if(ch=='-') fh=-1,ch=getchar();
    16     while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
    17     return fh*res;
    18 }
    19 LL gl()
    20 {
    21     LL res=0,fh=1;char ch=getchar();
    22     while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    23     if(ch=='-') fh=-1,ch=getchar();
    24     while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
    25     return fh*res;
    26 }
    27 LL n,m;
    28 LL a[3005][3005];
    29 LL s[3005],f[3005],h[3005],t;
    30 LL ans;
    31 
    32 int main()
    33 {
    34     memset(f,0,sizeof(f));
    35     memset(s,0,sizeof(s));
    36     memset(h,0,sizeof(h));    
    37     n=gl(),m=gl();
    38     LFor(i,1,n)     
    39         LFor(j,1,m) a[i][j]=gl();
    40     t=0;
    41     ans=0;
    42     LFor(i,1,n)
    43     {
    44         t=0;
    45         LFor(j,1,m)
    46         {
    47             if(!a[i][j]) h[j]=i;
    48             while(t&&h[s[t]]<h[j]) t--;
    49             s[++t]=j;
    50             f[t]=f[t-1]+(i-h[s[t]])*(s[t]-s[t-1]);
    51             ans+=f[t];
    52         }
    53     }
    54     cout<<ans<<endl;
    55     return 0;
    56 }
    View Code
  • 相关阅读:
    element-ui日期筛选:选择日期即触发查询
    js点击按钮复制内容到粘贴板
    axios配置及使用(发起请求时带上token)
    axios + vue导出excel文件
    textarea与标签组合,点击标签填入标签内容,再次点击删除内容(vue)
    vue复制textarea文本域内容到粘贴板
    ElementUI动态表格数据转换formatter
    elementUI图片墙上传
    高德地图模糊搜索地址(elementUI)
    elementUI表单验证
  • 原文地址:https://www.cnblogs.com/3soon/p/11530412.html
Copyright © 2011-2022 走看看