• [CF1392H] ZS Shuffles Cards


    [题目链接]

    https://codeforces.com/contest/1392/problem/H

    [题解]

    首先注意到抽到两次 "鬼牌" 的相邻时间间隔始终是固定的。

    不妨将每次抽到一张鬼牌并重排牌序之前的抽卡流程为一次 "迭代"。 考虑一次 "迭代" 的期望轮数。

    (E(x) = frac{n}{n + m} + 2 cdot frac{n}{n + m} cdot frac{m}{n + m - 1} + 3 cdot frac{n}{n + m} cdot frac{n - 1}{n + m - 1} cdot frac{m}{n + m - 2} + ... + = sum_{i}{i * frac{m}{n + m + 1 - i} prod_{j}{frac{n - j}{n + m - j}}})

    (w_{k} = prod_{j=0}^{k - 2}{frac{n - j}{n + m - j}}) , 可以通过递推的方式在 (O(NlogN)) 时间内求解 (E(x))

    接着考虑期望需要多少轮迭代才能抽到所有的牌。

    不妨设 (f_{k}) 表示还有 (k) 张不在牌堆里的牌期望轮数。

    那么有 (frac{m}{m + k}) 的概率抽到 (Joker) , 从而结束一轮迭代。

    另有 (frac{k}{m + k}) 的概率抽到一张需要的牌 , 转化为 ((k - 1)) 的子问题。

    也就是说 (f_{k} = frac{m}{m + k}(f_{k} + 1) + frac{k}{m + k}f_{k - 1})

    解得 (f_{k} = f_{k - 1} + frac{m}{k})

    也就是说 (f_{n} = f_{1} + sum_{i = 2}^{n}{frac{m}{i}})

    (f_{1}) 显然为 (frac{1}{frac{1}{m + 1}} = m + 1) , 于是 (f_{n} = 1 + msum_{i = 1}^{n}{frac{1}{i}})

    至此我们成功地在线性时间内求解了 (f)

    答案显然为 (E(x)f(n))。 这样就可以做到 (O(NlogN)) 的优秀复杂度了。

    但事实上 (E(x)) 可以不通过递推得到 , 考虑期望的线性性 , 在一轮迭代中 , 每张数字牌都有 (frac{1}{m + 1}) 的概率被抽出 , 概率相加就是期望(还要加上 (1) , 表示最终摸到一张 (Joker))。

    (E(x) = frac{n}{m + 1} + 1)

    这样做时间复杂度为 (O(N)) (瓶颈在于线性求逆元)。

    [代码]

    #include<bits/stdc++.h>
     
    using namespace std;
     
    typedef long long LL;
     
    #define rep(i , l , r) for (int i = (l); i < (r); ++i)
     
    const int mod = 998244353;
     
    int N , M;
     
    inline void inc(int &x , int y) {
    	x = x + y < mod ? x + y : x + y - mod;
    }
    inline int qPow(int a , int b) {
    	int c = 1;
    	for (; b; b >>= 1 , a = 1LL * a * a % mod) if (b & 1) c = 1LL * c * a % mod;
    	return c;
    }
     
    int main() {
    	
    	 scanf("%d%d" , &N , &M); 
    	 int ans = 1LL * (N + M + 1) * qPow(M + 1 , mod - 2) % mod;
    	 int ex = 0;
    	 for (int i = 1; i <= N; ++i) inc(ex , qPow(i , mod - 2));
    	 ex = (1ll * ex * M % mod + 1) % mod;
    	 printf("%d
    " , 1ll * ans * ex % mod);
         return 0;
    }
  • 相关阅读:
    在Pycharm中使用GitHub
    Ubuntu20.04开启root账户的方法步骤
    使用git push文件到gitee
    Dell主机安装win10+Ubuntu20.04双系统
    Golang select 基础语法与用法
    Golang websocket 实现消息推送
    Golang + gRPC 实践
    Golang实现RPC
    unigui+fastReport实现web打印方案(43)
    [控件] 加强版 TOneSelection (改良自 Berlin 10.1 TSelection)
  • 原文地址:https://www.cnblogs.com/evenbao/p/14359288.html
Copyright © 2020-2023  润新知