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 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?!(单调栈)