题解-骰子
题目
Description
桌面上有 \(2\) 只完全相同的骰子,定义一次操作如下:将桌子上的骰子全部抛出,然后去掉那些奇数点的骰子,如果桌子上还有骰子,则重复上面的操作。
求操作 \(n\) 次后,桌面上至少还有一个骰子的概率。
为了方便起见,你只需要输出概率对 \(19260817\) 取模的结果。
Input
\(1\) 行 \(1\) 个整数 \(n\)
保证 \(n\) 在long long范围内
Output
\(1\) 行 \(1\) 个结果 对 \(19260817\) 取模的结果
Sample Input
1
Sample Output
4815205
HINT
对于 \(40\%\) 的数据 : \(1 \le nnn \le 1000000\)
对于 \(100\%\) 的数据 : \(n\) 在long long范围内
题解
说点题外话:这两个字读骰子(tóu zǐ)
容易看出,解此题分两部分:
- 把概率对应的分数算出来
- 把分数取模
关于分数取模
\(\frac{a}{b} \mod p\)就是 \(a \times b\texttt{关于}p\texttt{的乘法逆元}\)
即
核心在于求解\(b\)关于\(p\)的乘法逆元。
即求解
概率
题目求桌面上至少还有一个骰子的概率,所以就是剩一个骰子和剩两个骰子的概率。
每个骰子的奇数和偶数的概率相等,都是\(\frac{1}{2}\)。
每次操作后,\(2\)个骰子都留下和都去掉的概率都是\(\frac{1}{4}\)。
由\(2\)个骰子到\(1\)个的概率是\(\frac{1}{2}\)
当只剩\(1\)个骰子时,剩下和去掉的概率均是\(\frac{1}{2}\)。
RT:

定义在第\(n\)次操作后,剩两个、一个、恰好零个的概率分别为\(f_2(n)\)、\(f_1(n)\)、\(f_0(n)\)。
剩两个的概率比较好求:
剩一个的概率是由2个到1个的概率加由1个到1个的概率:
代入\(f_2(n)=\frac{1}{4^n}\),
代入\(f_1(n-1)\),
整理得,
代入\(f_1(n-2)\),
整理得,
到这里,已经容易看出:(每次分母除2,求和)
另有,
容易得出,
其实就是首项为\(\frac{2^{n-1}}{2\times 4^{n-1}}=\frac{1}{2^n}\)末项为\(\frac{1}{2\times4^{n-1}}\)的等比数列。
所以其和就是,
答案就是,
Code
附上本蒟蒻929B代码:
#include <cstdio>
#include <algorithm>
#define MOD 19260817
using namespace std;
long long fast_pow(long long a, long long b) {
if (b == 0) return 1;
if (b == 1) return a;
long long half_result = fast_pow(a, b / 2);
if (b % 2 == 0) return half_result * half_result % MOD;
else return (((half_result * half_result) % MOD) * a) % MOD;
}
long long exgcd(long long a, long long b, long long &x, long long &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
long long result = exgcd(b, a % b, x, y);
long long t = x;
x = y;
y = t - (a / b) * y;
return result;
}
int main() {
long long n;
scanf("%lld", &n);
long long a = fast_pow(2, n + 1) - 1;
a %= MOD;
if (a < 0) a += MOD;
long long b = fast_pow(4, n);
long long x, y;
long long g = exgcd(b, MOD, x, y);
if (g != 1) printf("qwq");
while (x < 0) x += MOD;
x *= a;
x %= MOD;
printf("%lld\n", x);
return 0;
}

浙公网安备 33010602011771号