题意
给出一种生成区间的方式:
首先从 ([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);
}