hdu 6052(暴力枚舉 容斥)
阿新 • • 發佈:2017-07-28
ios blog math const href tail sdn target light
思路來自 http://blog.csdn.net/u014258433/article/details/76223343
我是用滑動窗口實現的。
代碼:
#include <cstdio> #include <cstring> #include <cmath> #include <iostream> using namespace std; const int maxn = 100; const long long mod = 1000000007; int a[maxn + 10][maxn + 10]; int pre[maxn * maxn + 10][maxn + 10]; long long dp[maxn + 10][maxn + 10]; int main() { for(int i = 1; i <= maxn; ++i) { for(int j = 1; j <= maxn; ++j) { if(i == 1 && j == 1) dp[i][j] = 1; else if(i == 1) dp[i][j] = dp[i][j - 1] + j; else if(j == 1) dp[i][j] = dp[i - 1][j] + i; else dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + i * j; } } int T; scanf("%d", &T); while(T--) { int n, m; scanf("%d%d", &n, &m); memset(pre, 0, sizeof(pre)); for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { scanf("%d", &a[i][j]); } } long long ans = 0; for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { int color = a[i][j]; int l = j, r = j; int MAX = pre[color][j]; ans += (long long)(i - MAX) * (n - i + 1); while(l - 1 > 0 && pre[color][l - 1] != i || r + 1 <= m) { if(l - 1 > 0 && pre[color][l - 1] != i && r + 1 <= m) { int tmp1 = max(pre[color][l - 1], MAX), tmp2 = max(pre[color][r + 1], MAX); if(tmp1 < tmp2) { ans += (long long)(i - tmp1) * (j - l + 2) * (n - i + 1) * (r - j + 1) - (long long)(i - tmp1) * (j - l + 1) * (n - i + 1) * (r - j + 1); --l; MAX = tmp1; } else { ans += (long long)(i - tmp2) * (j - l + 1) * (n - i + 1) * (r - j + 2) - (long long)(i - tmp2) * (j - l + 1) * (n - i + 1) * (r - j + 1); ++r; MAX = tmp2; } } else if(l - 1 > 0 && pre[color][l - 1] != i) { int tmp = max(pre[color][l - 1], MAX); ans += (long long)(i - tmp) * (j - l + 2) * (n - i + 1) * (r - j + 1) - (long long)(i - tmp) * (j - l + 1) * (n - i + 1) * (r - j + 1); --l; MAX = tmp; } else { int tmp = max(pre[color][r + 1], MAX); ans += (long long)(i - tmp) * (j - l + 1) * (n - i + 1) * (r - j + 2) - (long long)(i - tmp) * (j - l + 1) * (n - i + 1) * (r - j + 1); ++r; MAX = tmp; } // cout << "l == " << l << " r == " << r << endl; // cout << "cur_ans == " << ans << endl; } // cout << "l == " << l << " r == " << r << endl; // cout << "ans == " << ans << endl; pre[color][j] = i; } } printf("%.9f\n", ans * 1.0 / dp[n][m]); } return 0; }
hdu 6052(暴力枚舉 容斥)