zoukankan      html  css  js  c++  java
  • HDU 6052 To my boyfriend(悬线法)

    【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6052

    【题目大意】

      给出一个数字矩阵,求子矩阵期望数字种数

    【题解】

      我们统计[x,y]为其所表示的数字的最左上方的矩形数量,即该格子的贡献值,
      我们用悬线法将上边界上移,调整左右边界保证[x,y]为数字左上边界,
      那么x及其以下的部分都可以作为下边界,顺序统计即可,
      由于障碍点的顺序设置保证了二维的偏序性,不会出现重复统计贡献。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long LL;
    const int N=110;
    int n,m,c,l[N],r[N],row[N*N][N];
    LL Cal(int x,int y,int c){
        LL res=0;
        for(int i=1;i<=x;i++)l[i]=0,r[i]=m+1;
        for(int i=1;i<y;i++)l[row[c][i]]=i;
        for(int i=m;i>y;i--)r[row[c][i]]=i; 
        int h=row[c][y];
        for(int i=x-1;i>h;i--)l[i]=max(l[i],l[i+1]),r[i]=min(r[i],r[i+1]);
        for(int i=x;i>h;i--)res+=(LL)(r[i]-y)*(y-l[i])*(n-x+1);
        return res;
    }
    int T; 
    int main(){
        scanf("%d",&T);
        while(T--){
            memset(row,0,sizeof(row));
            scanf("%d%d",&n,&m);
            LL ans=0,tot=0;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    scanf("%d",&c);
                    ans+=Cal(i,j,c);
                    row[c][j]=i;
                    tot+=1LL*i*j;
                }
            }printf("%.9f
    ",1.0*ans/tot);
        }return 0;
    }
  • 相关阅读:
    Linux 组管理、权限
    Linux 简单文本处理
    Linux 基础内容
    Python selectors实现socket并发
    Python select实现socket并发
    SOA专博收藏
    高亮显示代码编辑器控件【转】
    WCF开源开发框架Zyan
    ubuntu中文实训手册
    Easy UI treegrid 分页实例
  • 原文地址:https://www.cnblogs.com/forever97/p/hdu6052.html
Copyright © 2011-2022 走看看