AGC019F Yes or No
思路
先思考最优策略是什么,如果你想尽可能多的对,那么一定是答当前剩的数目最多的答案。比如当前还有 \(x\) 道 \(\text{YES}\),\(y\) 道 \(\text{NO}\),在 \(x>y\) 时一定答 \(\text{YES}\),\(x<y\) 时一定答 \(\text{NO}\),\(x=y\) 时两者皆可,不妨设他都选 \(\text{YES}\)。按这样答至少都能对 \(\max(n,m)\) 道题,我们就只需考虑 \(x=y\) 时产生的贡献。
现在还剩下 \(2x\) 道题,那么之前就选了 \(n+m-2x\) 道题,其中有 \(n-x\) 道 \(\text{YES}\),方案数为 \(C_{n+m-2x}^{n-x}\)(我们默认了 \(x=y\) 时选 \(\text{YES}\))。之后就会在 \(2x\) 道题中选 \(x\) 道 \(\text{YES}\),方案数为 \(C_{2x}^x\),乘起来就是总方案数。每种方案都有 \(\frac{1}{2}\) 的概率选对,他的贡献就为 \(\frac{1}{2}\)。总选择方案为 \(C_{n+m}^{n}\),那么这部分的答案便为 \(\dfrac{1}{2} \times \dfrac{\sum\limits_{x=1}^{\min(n,m)}C_{n+m-2x}^{n-x}C_{2x}^x}{C_{n+m}^{n}}\),加上 \(\max(n,m)\) 就是最后的答案了。
code
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int mod=998244353,N=1e6+5;
ll qpow(ll x,ll y){
ll res=1;
while(y>0){
if(y&1)res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
ll n,m;
ll fac[N],inv[N],ans;
ll C(ll x,ll y){
if(x<0||y<0||x<y)return 0;
return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
int main(){
cin>>n>>m;
fac[0]=inv[0]=1;
for(int i=1;i<=max(n,m)*2;++i)fac[i]=fac[i-1]*i%mod;
inv[max(n,m)]=qpow(fac[max(n,m)],mod-2);
for(int i=max(n,m)-1;i>=1;--i)inv[i]=inv[i+1]*(i+1)%mod;
for(int i=1;i<=min(n,m);++i)ans=(ans+C(2*i,i)*C(n+m-2*i,n-i)%mod)%mod;
ans=ans*qpow(2,mod-2)%mod*qpow(C(n+m,n),mod-2)%mod;
ans=(ans+max(n,m))%mod;
cout<<ans;
return 0;
}