hdu 6052(暴力枚举 容斥)

思路来自 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;
}

  

时间: 2024-10-10 06:24:12

hdu 6052(暴力枚举 容斥)的相关文章

HDU 5321 Beautiful Set 容斥 (看题解)

HDU 5321 感觉有点抗拒这种题目, 看到就感觉自己不会写,其实就是个沙雕题, 感觉得找个时间练练这种题. g[ i ] 表示gcd为 i 的倍数的方案数, f[ i ] 表示gcd为 i 的方案数, 然后先算g[ i ]然后直接容斥. #pragma GCC optimize(2) #pragma GCC optimize(3) #include<bits/stdc++.h> #define LL long long #define LD long double #define ull

HDU 4135 Co-prime(容斥+数论)

Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5526    Accepted Submission(s): 2209 Problem Description Given a number N, you are asked to count the number of integers between A and B

HDU 5297 Y sequence 容斥/迭代

Y sequence Problem Description Yellowstar likes integers so much that he listed all positive integers in ascending order,but he hates those numbers which can be written as a^b (a, b are positive integers,2<=b<=r),so he removed them all.Yellowstar ca

HDU 3970 Harmonious Set 容斥欧拉函数

链接 题解:www.cygmasot.com/index.php/2015/08/17/hdu_3970 给定n 求连续整数[0,n), 中任意选一些数使得选出的数和为n的倍数的方法数 ...并不会如何递推.. 思路: 然后这是公式:点击打开链接 a(n) = 1/n * sum_{d divides n and d is odd} 2^(n/d) * phi(d). d最大是n,也就是1e9,要计算1e9的phi,所以容斥来算phi. #pragma comment(linker, "/STA

HDU 4135 Co-prime(组合+容斥)

Problem Description Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N. Two integers are said to be co-prime or relatively prime if they have no common positive divisors other tha

HDU 4609 3-idiots FFT+容斥

一点吐槽:我看网上很多分析,都是在分析这个题的时候,讲了半天的FFT,其实我感觉更多的把FFT当工具用就好了 分析:这个题如果数据小,统计两个相加为 x 的个数这一步骤(这个步骤其实就是求卷积啊),完全可以母函数,无奈数据很大,就用FFT了 然后难点在于最后的统计,要减去自身,两个都大的,一大一小,包含自身,这是用到了容斥,再做相似的题的时候,应该多看看这方面 注:再次高度仰慕kuangbin神,这是我FFT的第二题,也是第二次用kuangbin FFT模板 #include <stdio.h>

HDU 1695 GCD(容斥定理)

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7529    Accepted Submission(s): 2773 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y

HDU 4135 Co-prime(容斥:二进制解法)题解

题意:给出[a,b]区间内与n互质的个数 思路:如果n比较小,我们可以用欧拉函数解决,但是n有1e9.要求区间内互质,我们可以先求前缀内互质个数,即[1,b]内与n互质,求互质,可以转化为求不互质,也就是有除1的公因数.那么我们把n质因数分解,就能算出含某些公因数的不互质的个数.因为会重复,所以容斥解决.因为因数个数可能很多(随便算了一个20!> 2e18,所以质因数分解个数不会超过20个),我们可以用二进制来遍历解决. #include<set> #include<map>

题解报告:hdu 4135 Co-prime(容斥定理入门)

Problem Description Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N.Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than