码迷,mamicode.com
首页 > 其他好文 > 详细

[CF696C] PLEASE - 概率

时间:2021-03-08 13:48:36      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:inline   ase   bit   define   res   cout   cpp   clu   ||   

[CF696C] PLEASE - 概率

Description

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

Solution

根据题意,很容易得到递推式

\(a_{n+1} = \frac 1 2 (1-a_n)\)

求一下通项,发现分子分母一定是互质的,于是就完了

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int mod = 1e9 + 7;

namespace math_mod
{
    int c__[5005][5005], fac__[3000005];

    int qpow(int p, int q)
    {
        return (q & 1 ? p : 1) * (q ? qpow(p * p % mod, q / 2) : 1) % mod;
    }

    int inv(int p)
    {
        return qpow(p, mod - 2);
    }

    int fac(int p)
    {
        if (p <= 3000000)
            return fac__[p];
        if (p == 0)
            return 1;
        return p * fac(p - 1) % mod;
    }

    int __fac(int p)
    {
        return fac(p);
    }

    int ncr(int n, int r)
    {
        if (r < 0 || r > n)
            return 0;
        return fac(n) * inv(fac(r)) % mod * inv(fac(n - r)) % mod;
    }

    void math_presolve()
    {
        fac__[0] = 1;
        for (int i = 1; i <= 3000000; i++)
        {
            fac__[i] = fac__[i - 1] * i % mod;
        }
        for (int i = 0; i <= 5000; i++)
        {
            c__[i][0] = c__[i][i] = 1;
            for (int j = 1; j < i; j++)
                c__[i][j] = c__[i - 1][j] + c__[i - 1][j - 1], c__[i][j] %= mod;
        }
    }

    int __c(int n, int r)
    {
        if (r < 0 || r > n)
            return 0;
        if (n > 5000)
            return ncr(n, r);
        return c__[n][r];
    }
}

using namespace math_mod;

signed main()
{
    ios::sync_with_stdio(false);
    int ans = 1;
    int n;
    cin >> n;

    math_presolve();

    int flag = 1;

    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        if (x % 2 == 0)
            flag = 0;
        x %= (mod - 1);
        ans *= x;
        ans %= (mod - 1);
    }

    int x = qpow(2, (ans) % mod);
    x *= inv(2);
    x %= mod;
    int p = (x + (flag ? -1 : 1) + mod) % mod * inv(3) % mod;
    int q = x;
    cout << p << "/" << q << endl;
}

[CF696C] PLEASE - 概率

标签:inline   ase   bit   define   res   cout   cpp   clu   ||   

原文地址:https://www.cnblogs.com/mollnn/p/14493986.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!