HDU 6052 To my boyfriend 思维 + 枚举(计数)

来源:互联网 发布:邮箱服务器地址和端口 编辑:程序博客网 时间:2024/06/18 08:58

传送门:HDU6052

题意:给出一个n*m的矩阵,每个点有一种颜色,定义矩阵的val为矩阵中不同颜色的数量,问任意一个子矩阵的val的期望为多少。

思路:我是直接看了一篇讲解的想不理解都难的博客:点击打开链接


代码:

#include<bits/stdc++.h>#define ll long long#define pb push_back#define fi first#define se second#define pi acos(-1)#define inf 0x3f3f3f3f#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define rep(i,x,n) for(int i=x;i<n;i++)#define per(i,n,x) for(int i=n;i>=x;i--)using namespace std;typedef pair<int,int>P;const int MAXN=10010;int gcd(int a,int b){return b?gcd(b,a%b):a;}int n, m;vector<P> color[MAXN];vector<int> Y[110];int last[110];ll calc(int col){ll ans = 0;memset(last, 0, sizeof(last));for(int o = 0; o < color[col].size(); o++){int tx = color[col][o].fi, ty = color[col][o].se;for(int i = 1; i <= m; i++)Y[i].clear();for(int i = 1; i <= m; i++)if(last[i])Y[last[i]].pb(i);int tl = 1, tr = m;bool flag = 0;for(int i = tx; i >= 1; i--){for(int j = 0; j < Y[i].size(); j++){int tmp = Y[i][j];if(tmp < ty)tl = max(tl, tmp + 1);else if(tmp > ty)tr = min(tr, tmp - 1);else{flag = 1;break;}}if(flag) break;ans += 1ll * (n - tx + 1) * (ty - tl + 1) * (tr - ty + 1); }last[ty] = tx;}return ans;}int main(){int T, c;scanf("%d", &T);while(T--){scanf("%d %d", &n, &m);for(int i = 0; i <= n * m; i++)color[i].clear();for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)scanf("%d", &c), color[c].pb(P(i, j));for(int i = 0; i <= n * m; i++)if(color[i].size())sort(color[i].begin(), color[i].end());ll sum = 0, ans = 0;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)sum += 1ll * i * j;for(int i = 0; i <= n * m; i++)if(color[i].size())ans += calc(i);printf("%.9lf\n", (double)ans * 1.0 / sum);} return 0;}