AGC019F Yes or No

洛谷 AT

思路

先思考最优策略是什么,如果你想尽可能多的对,那么一定是答当前剩的数目最多的答案。比如当前还有 \(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;
}

posted @ 2024-01-19 20:51  SunsetLake  阅读(7)  评论(0编辑  收藏  举报
-->