[AGC019F] Yes or No

首先,不难得出选 YES 答对的概率是 $\frac{N}{N + M}$,选 NO 答对的概率是 $\frac{M}{N+M}$。

于是我们有如下结论:

假设 $N > M$,我们必定选 YES;相反 $M > N$,则必定选 NO

由于 YESNO 没有本质之分,同时出于简化问题的考虑,不妨钦定 $N \geq M$。

接着,易发现答案保底有 $\max(N,M)$,即 $N>M$ 时带来的贡献。原因很简单:假设当前答案是 YES,答对了算进贡献;当前答案是 NO,那么这一题答错了、但是 $N$ 的值依旧没变,而 $M$ 却减小了。如果按照这样下去(最坏情况),最后 $M=0$ 之后你就能连续猜对 $N$ 次。

之后考虑 $N=M$ 所带来的贡献。其实就是拿“期望出现的 $N=M$ 的局面数”乘以 $\frac{1}{2}$(不管选 YESNO 都有 $\frac{1}{2}$ 的概率答对)。具体的,我们对于前者,进行拆贡献。现在问题就转化为了求出现某个给定局面的概率,组合数求解即可。

#include <bits/stdc++.h>
#define FL(i, a, b) for(int i = (a); i <= (b); i++)
#define FR(i, a, b) for(int i = (a); i >= (b); i--)
using namespace std;
const int N = 1e6 + 10, p = 998244353;
int n, m, s, ans, fac[N];
int qpow(int a, int b){
    int ans = 1;
    while(b){
        if(b & 1) ans = 1ll * ans * a % p;
        b >>= 1, a = 1ll * a * a % p;
    }
    return ans;
}
int inv(int x){return qpow(x, p - 2);}
int C(int n, int m){
    if(n < m || n < 0) return 0; if(!m) return 1;
    return 1ll * fac[n] * inv(fac[n - m]) % p * inv(fac[m]) % p;
}
int main(){
    scanf("%d%d", &n, &m); if(m > n) swap(n, m);
    fac[0] = 1;
    FL(i, 1, n + m) fac[i] = 1ll * fac[i - 1] * i % p;
    FL(i, 1, m)
        (ans += 1ll * C(i * 2, i) * C(n - i + m - i, n - i) % p) %= p;
    printf("%d\n", (1ll * ans * inv(C(n + m, n)) % p * inv(2) + n) % p);
    return 0;
} 
posted @ 2023-07-26 11:38  徐子洋  阅读(15)  评论(0)    收藏  举报  来源