hdu 6052 - To my boyfriend

Posted 太阳星人FxxL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 6052 - To my boyfriend相关的知识,希望对你有一定的参考价值。

题目

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

 

  分开考虑每种颜色

  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]))

 

 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\n",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 }

 

以上是关于hdu 6052 - To my boyfriend的主要内容,如果未能解决你的问题,请参考以下文章

hdu 6052(暴力枚举 容斥)

HDU5800 To My Girlfriend(DP)

HDU 5800 To My Girlfriend(单调DP)

hdu 6058 To my boyfriend (计算贡献,思维)

HDU多校第四场1005 Didn‘t I Say to Make My Abilities Average in the Next Life?! 单调栈+莫队

HDU多校4 - 6989 Didn‘t I Say to Make My Abilities Average in the Next Life?!(单调栈)