zoukankan      html  css  js  c++  java
  • hdu 6052 To my boyfriend

    题目

      OvO click here http://acm.hdu.edu.cn/showproblem.php?pid=6052

      (2017 Multi-University Training Contest - Team 2 - 1008) 

      分开考虑每种颜色

      pre[i][j]代表第j列最近一个i颜色的行数,ppre是次近

      calcu(li,ji,x,y,clr)表示从col=li到col=ri,计算(x,y)点对mp[x][y]=clr颜色有贡献的矩形的个数(其实并不是,准确说是(n-i+1)*(calcu(1,m,i,j,mp[i][j])-calcu(1,j-1,i,j,mp[i][j])-calcu(j+1,m,i,j,mp[i][j]))才是有贡献的矩形的个数)

      记每个子矩阵中,对于每种颜色,记最上(同层则最左)的那个点对该矩阵该颜色有贡献.

      接下来然后搜索每个点,对于每个点用单调栈计算合法矩阵个数,对于点(i,j)就是前文提过的(n-i+1)*(calcu(1,m,i,j,mp[i][j])-calcu(1,j-1,i,j,mp[i][j])-calcu(j+1,m,i,j,mp[i][j]))

      calcu函数中,对于每个扫到的列,如果它的高度小于当前栈顶的高度,那么把栈顶的元素弹出来,并且把宽度加到当前这个列中。因为栈中超出当前列的高度的那部分已经不会再对矩形个数产生贡献。

      calcu中tmp的作用其实就是能产生贡献的方块的左上角的坐标个数

      (本思路来自某其他博客) 

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <cmath>
     6 
     7 using namespace std;
     8 
     9 typedef long long ll;
    10 
    11 const ll M=124;
    12 
    13 struct node
    14 {
    15     ll h,x;
    16 }    stk[M];
    17 
    18 ll n,m;
    19 ll mp[M][M];
    20 ll pre[M*M][M],ppre[M*M][M];    //i,j the row of color=i, in col=j 
    21 ll lstk;
    22 double ans;
    23 
    24 void init()
    25 {
    26     ans=0;
    27     memset(pre,0,sizeof(pre));    
    28     memset(ppre,0,sizeof(ppre));
    29 }
    30 
    31 //calcu the num of appropriate matrix whose buttom is row x, from col li to col ri, 
    32 ll calcu(ll li,ll ri,ll x,ll y,ll clr)    
    33 {
    34     node p;
    35     ll k,tmp=0;
    36     ll ret=0;
    37     lstk=0;
    38     for(k=li;k<=ri;k++)
    39     {
    40         if(pre[clr][k]==x && k>=y)
    41             p.h=x-ppre[clr][k];
    42         else 
    43             p.h=x-pre[clr][k];
    44         p.x=1;
    45         if(p.h==0)
    46         {
    47             tmp=0;
    48             lstk=0;
    49             continue;
    50         }
    51         while(lstk>0 && stk[lstk].h>p.h)
    52         {
    53             tmp-=stk[lstk].h*stk[lstk].x;
    54             p.x+=stk[lstk--].x;
    55         }
    56         stk[++lstk]=p;
    57         tmp+=p.h*p.x;
    58         ret+=tmp;
    59     }
    60     return ret;
    61 }
    62 
    63 void solve()
    64 {
    65     ll i,j;
    66     for(i=1;i<=n;i++)
    67     {
    68         for(j=1;j<=m;j++)    
    69         {
    70             ppre[mp[i][j]][j]=pre[mp[i][j]][j];
    71             pre[mp[i][j]][j]=i;
    72         }
    73         for(j=1;j<=m;j++)
    74             ans+=1ll*(n-i+1)*(calcu(1,m,i,j,mp[i][j])-calcu(1,j-1,i,j,mp[i][j])-calcu(j+1,m,i,j,mp[i][j]));
    75     }
    76     ans=ans*4/(1ll*n*m*(n+1)*(m+1));
    77     printf("%.9lf
    ",ans);
    78 }
    79 
    80 int main()
    81 {
    82     ll i,j,T;
    83     cin>>T;
    84     while(T--)
    85     {
    86         scanf("%lld%lld",&n,&m);
    87         for(i=1;i<=n;i++)
    88         for(j=1;j<=m;j++)
    89             scanf("%lld",&mp[i][j]);
    90         init();
    91         solve();
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    element ui 表单清空
    element ui 覆盖样式 方法
    element ui 修改表单值 提交无效
    element ui 抽屉里的表单输入框无法修改值
    element ui 抽屉首次显示 闪烁
    css 左侧高度 跟随右侧内容高度 自适应
    PICNUF框架
    elementui 抽屉组件标题 出现黑色边框
    vue 子组件跨多层调用父组件中方法
    vue 编辑table 数据 未点击提交,table里的数据就发生了改变(深拷贝处理)
  • 原文地址:https://www.cnblogs.com/FxxL/p/7250017.html
Copyright © 2011-2022 走看看