【2019 CCPC 江西省赛】HDU 6574 Rng 打表找规律

题目链接

题意

给出一种生成区间的方式:

首先从 ([1,n]) 中随机生成 (r),然后在区间 ([1,r]) 中生成 (l)

生成两个区间,问这两个区间相交的概率。

做题过程

本来想打表来着,但是一看数据范围,公式应该是递推求东西,就没写打表。

分两种情况和队友一起推了第一种情况,然后去写 C 了。

最后队友自己推第二种情况,化简之后 A 了。而我还在找 C 的bug(题意读错了。。)

赛后打表试了试,发现就是 ((n+1)/(2*n))

打表代码

#include <bits/stdc++.h>
#define fuck system("pause")
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 1e9 + 7;
const int seed = 12289;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 10;

int judge(int l, int r, int L, int R)
{
    if (max(l, L) <= min(R, r))
        return 1;
    return 0;
}
vector<int> up, down;
void solve(int n)
{
    up.clear(), down.clear();
    for (int i = 1; i <= n; i++) {
        for (int j = i; j <= n; j++) {
            for (int k = 1; k <= n; k++) {
                for (int l = k; l <= n; l++) {
                    if (judge(i, j, k, l)) {
                        up.pb(1), down.pb(n * n * j * l);
                    }
                }
            }
        }
    }
    int rel = down[0];
    for (int i = 1; i < down.size(); i++) {
        rel = rel / __gcd(rel, down[i]) * down[i];
    }
    int sum = 0;
    for (int i = 0; i < up.size(); i++) {
        sum += rel / down[i] * up[i];
    }
    int gcd = __gcd(rel, sum);
    printf("%d/%d
", sum / gcd, rel / gcd);
}
int main()
{
    for (int i = 1; i <= 10; i++) {
        solve(i);
    }
    return 0;
}

AC代码

#include <bits/stdc++.h>
#define fuck system("pause")
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 1e9 + 7;
const int seed = 12289;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 10;

ll qpow(ll a, ll b)
{
    ll ans = 1;
    a %= mod;
    while (b) {
        if (b & 1) {
            ans = (ans * a) % mod;
        }
        b >>= 1;
        a = a * a % mod;
    }
    return ans % mod;
}

int main()
{
    ll n;
    scanf("%lld", &n);
    ll up = (n + 1) / __gcd(n + 1, 2 * n);
    ll down = (2 * n) / __gcd(n + 1, 2 * n);
    printf("%lld
", up * qpow(down, mod - 2) % mod);
}
原文地址:https://www.cnblogs.com/valk3/p/13832361.html