首页 > 代码库 > CF697E && CF696C PLEASE

CF697E && CF696C PLEASE

题意:给你三个杯子,一开始钥匙放在中间的杯子里,然后每一回合等概率将左右两个杯子中的一个与中间杯子交换。求n回合之后钥匙在中间杯子的概率。这里要求概率以分数形式输出,先化成最简,然后对1e9 + 7取模。

题解:首先我们可以轻易得到一个递推式:$ d[i] = \frac{{1 - d[i - 1]}}{2} $

但递推式是不行的,我们要得到一个封闭形式。

运用数列技巧,我们可以进行如下变换:$d[i] - \frac{1}{3} =  - \frac{1}{2}(d[i - 1] - \frac{1}{3})$

那么我们有 $d[n] = \frac{{{{( - 1)}^n} + {2^{n - 1}}}}{{3 \times {2^{n - 1}}}}$

其中我们发现,${{{( - 1)}^n} + {2^{n - 1}}}$ 一定是3的倍数,且商一定是奇数,所以与剩下部分互质

也即  $p = \frac{{{{( - 1)}^n} + {2^{n - 1}}}}{3}$  $q = {2^{n - 1}}$

带进去算就好了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define mod 1000000007
 5 
 6 inline LL read() {
 7     LL x = 0, f = 1; char a = getchar();
 8     while(a < 0 || a > 9) { if(a == -) f = -1; a = getchar(); }
 9     while(a >= 0 && a <= 9) x = x * 10 + a - 0, a = getchar();
10     return x * f;
11 }
12 
13 int n, p = 2, q, f = 1;
14 
15 inline int fpow(int x, LL k) {
16     int ret = 1;
17     while(k) {
18         if(k & 1) ret = 1LL * ret * x % mod;
19         k /= 2; x = 1LL * x * x % mod;
20     }
21     return ret;
22 } 
23 
24 int main() {
25     n = read();
26     LL tmp; int inv2 = fpow(2, mod -2), inv3 = fpow(3, mod - 2);
27     for(int i = 1; i <= n; i++) {
28         tmp = read();
29         f = 1LL * f * tmp % 2;
30         p = fpow(p, tmp);
31     }
32     q = 1LL * p * inv2  % mod;    
33     p = 1LL * (q + (f ? -1 : 1)) * inv3 % mod;
34     printf("%d/%d\n" ,p ,q);
35     return 0;
36 }

 

CF697E && CF696C PLEASE