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 }
  • 相关阅读:
    每日口语(6.12)
    The usage of thumb
    Chart相关网站
    每日口语(6.14)
    我为世界杯狂
    一个很简单的javascript问题,看你能否答对
    【转】理解伪元素:Before和:After
    JS BOM之location.hash详解
    JS BOM之location对象
    JS BOM之location.hash的用法
  • 原文地址:https://www.cnblogs.com/FxxL/p/7250017.html
Copyright © 2011-2022 走看看