zoukankan      html  css  js  c++  java
  • hdu-5749 Colmerauer(单调栈)

    题目链接:

    Colmerauer

    Time Limit: 10000/5000 MS (Java/Others)  

      Memory Limit: 131072/131072 K (Java/Others)



    Problem Description
     
    Peter has an n×m matrix M. Let S(a,b) be the sum of the weight all a×b submatrices of M. The weight of matrix is the sum of the value of all the saddle points in the matrix. A saddle point of a matrix is an element which is both the only largest element in its column and the only smallest element in its row. Help Peter find out all the value of S(a,b).

    Note: the definition of saddle point in this problem may be different with the definition you knew before.
     
    Input
     
    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

    The first contains two integers n and m (1n,m1000) -- the dimensions of the matrix.

    The next n lines each contain m non-negative integers separated by spaces describing rows of matrix M (each element of M is no greater than 106).
     
    Output
     
    For each test case, output an integer W=(a=1nb=1mabS(a,b)) mod 232.
     
    Sample Input
     
    3
    2 2
    1 1
    1 1
    3 3
    1 2 3
    4 5 6
    7 8 9
    3 3
    1 2 1
    2 3 1
    4 5 2
     
    Sample Output
     
    4
    600
    215
     
     
    题意:
     
    http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=718&pid=1003
     
    思路:
     
    把每个矩阵的值单独找出来复杂度太高,就考虑每个元素对答案的贡献,找出这个元素在
     
    对于矩阵种一个元素M(x,y)考虑他可以成为那些子矩阵的鞍点, 用单调队列之类的东西处理出a,b,c,d分别表示在第x行中, 这个元素在第y-a列到y+b列中都是唯一最小值; 第y列中, 这个元素在第x-cx+d行中都是唯一最大值.
    然后知道了这个范围就是找出有多少个矩阵包含这个元素以及这些矩阵的a*b;然后就是找到了一个公式,(a+b)*a*b*c*d*(c+d)/4;
     
    AC代码:
     
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <bits/stdc++.h>
    #include <stack>
    
    using namespace std;
    
    #define For(i,j,n) for(int i=j;i<=n;i++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    
    typedef  unsigned long long LL;
    
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
    
    const LL mod=1LL<<32;
    const double PI=acos(-1.0);
    const int inf=1e9;
    const int N=1e7+10;
    const int maxn=1000+10;
    const double eps=1e-8;
    
    
    int up[maxn][maxn],down[maxn][maxn],le[maxn][maxn],ri[maxn][maxn],a[maxn][maxn],pos[maxn];
    
    inline LL cal(int a,int b,int c,int d)
    {
        LL ans=1;
        ans=((LL)a*b*(a+b)/2)%mod;
        ans=((LL)c*d*(c+d)/2)%mod*ans%mod;
        return ans;
    }
    
    int main()
    {
            int t;
            read(t);
            while(t--)
            {
                mst(pos,0);
                int n,m;
                read(n);read(m);
                For(i,1,n)For(j,1,m)read(a[i][j]);
                For(i,1,n)
                {
                    int l=1,r=0;
                    For(j,1,m)
                    {
                            while(r>=l&&a[i][pos[r]]>a[i][j])r--;
                            le[i][j]=pos[r]+1;
                            pos[++r]=j;
                    }
                    l=m+1,r=m;
                    pos[m+1]=m+1;
                    for(int j=m;j>0;j--)
                    {
                        while(l<=r&&a[i][pos[l]]>a[i][j])l++;
                        ri[i][j]=pos[l]-1;
                        pos[--l]=j;
                    }
                }
    
                For(i,1,m)
                {
                    int l=1,r=0;
                    For(j,1,n)
                    {
                        while(r>=l&&a[pos[r]][i]<a[j][i])r--;
                        up[j][i]=pos[r]+1;
                        pos[++r]=j;
                    }
                    l=n+1,r=n;
                    pos[n+1]=n+1;
                    for(int j=n;j>0;j--)
                    {
                        while(l<=r&&a[pos[l]][i]<a[j][i])l++;
                        down[j][i]=pos[l]-1;
                        pos[--l]=j;
                    }
                }
                LL ans=0;
                For(i,1,n)
                {
                    For(j,1,m)
                    {
                        le[i][j]=j-le[i][j]+1;
                        ri[i][j]=ri[i][j]-j+1;
                        up[i][j]=i-up[i][j]+1;
                        down[i][j]=down[i][j]-i+1;
                        ans=(ans+cal(up[i][j],down[i][j],le[i][j],ri[i][j])*a[i][j])%mod;
                    }
                }
                print(ans);
            }
            return 0;
    }
    

      

     
  • 相关阅读:
    oracle的增删改查语句
    Oracle Rac11g 学习笔记
    怎么个下载别人网站上的字体icon图标fonts文件
    APICloud Studio 3和Apploader真机同步,同一个wifi却一直提示连接不到
    c#发qq邮箱,QQ邮箱当中开启“POP3/SMTP服务”获取授权码
    微信支付异步回调不返回xml,微信会重复多次异步通知
    阿里云C磁盘拓容,IIS日志记录开启关闭
    jsapi微信支付
    c#.Net手机网站对接支付宝接口对接全流程说明
    无法找到列 7 程序遍历超过Excel列数
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5704665.html
Copyright © 2011-2022 走看看