Hdu-6052 To my boyfriend(单调栈)
2017-07-28 00:44
435 查看
Dear Liao I never forget the moment I met with you. You carefully asked me: "I have a very difficult problem. Can you teach me?". I replied with a smile, "of course". You replied:"Given a matrix, I randomly choose a sub-matrix, what is the expectation of the number of**different numbers** it contains?" Sincerely yours, GuoInputThe first line of input contains an integer T(T≤8) indicating the number of test cases. Each case contains two integers, n and m (1≤n, m≤100), the number of rows and the number of columns in the grid, respectively. The next n lines each contain m integers. In particular, the j-th integer in the i-th of these rows contains g_i,j (0≤ g_i,j < n*m).OutputEach case outputs a number that holds 9 decimal places.Sample Input
1 2 3 1 2 1 2 1 2Sample Output
1.666666667Hint
6(size = 1) + 14(size = 2) + 4(size = 3) + 4(size = 4) + 2(size = 6) = 30 / 18 = 6(size = 1) + 7(size = 2) + 2(size = 3) + 2(size = 4) + 1(size = 6) 分析:我们考虑计算每种颜色的贡献和,我们将某个子矩阵中对答案有贡献的方格定义为这个子矩阵的所有同色方格中最高上左的那个(先上后左),然后我们再转来计算每个方格贡献的子矩阵个数,这个用单调栈可以O(n)计算,总复杂度O(n^3).
#include <bits/stdc++.h> #define N 105 using namespace std; typedef long long ll; struct thing { int x,n; thing(){}; thing(int a,int b){x = a,n = b;} }Stack ; int T,n,m,tot,c ,pre[N*N] ,Pre[N*N] ,vis[N*N]; ll ans; int Count(int l,int r,int i,int j,int col) { int sum = 0,t = 0,ans = 0; for(int k = l;k <= r;k++) { int d = (i == pre[col][k] && k >= j) ? i - Pre[col][k] : i - pre[col][k]; if(!d) t = sum = 0; else { thing u = thing(d,1); while(t && Stack[t].x >= u.x) { sum -= Stack[t].x*Stack[t].n; u.n += Stack[t].n; t--; } sum += u.x*u.n*1ll; Stack[++t] = u; ans += sum; } } return ans; } int main() { scanf("%d",&T); while(T--) { memset(pre,0,sizeof(pre)); memset(vis,0,sizeof(vis)); tot = 0,ans = 0; scanf("%d%d",&n,&m); for(int i = 1;i <= n;i++) for(int j = 1;j <= m;j++) { scanf("%d",&c[i][j]); if(!vis[c[i][j]]) tot++,vis[c[i][j]] = 1; } for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { Pre[c[i][j]][j] = pre[c[i][j]][j]; pre[c[i][j]][j] = i; } for(int j = 1;j <= m;j++) { int col = c[i][j]; ans += (n-i+1ll)*(Count(1,m,i,j,col) - Count(1,j-1,i,j,col) - Count(j+1,m,i,j,col)); } } printf("%.9f\n",ans*4.0/(n*(n+1)*m*(m+1))); } }
相关文章推荐
- HDU 6052 To my boyfriend(容斥+单调栈)
- 第二场 hdu 6052 To my boyfriend
- HDU 6052 To my boyfriend(悬线法)
- HDU 6052 2017 Multi-University Training Contest - Team 2 1008 To My Boyfriend:计数问题
- HDU-6052 To my boyfriend 思维
- HDU-6052 To my boyfriend 思维
- HDU 6052 To my boyfriend【思维】
- (2017多校训练第二场)HDU - 6052 To my boyfriend 思维题
- HDU-6052 To my boyfriend 思维
- HDU-6052 To my boyfriend 思维
- 2017多校联合第二场 1008题 hdu 6052 To my boyfriend 计数 单调队列
- hdu 6052 To my boyfriend(枚举+容斥)
- HDU 6052 To my boyfriend 期望 计数
- HDU 6052 To my boyfriend 思维 + 枚举(计数)
- HDU-6052 To my boyfriend 思维
- hdu 6052 To my boyfriend
- HDU 6052 To my boyfriend(概率 贡献)
- HDU-6052 To my boyfriend 思维
- 2017 多校训练第二场 HDU 6052 To my boyfriend
- hdu 6052 To my boyfriend