题解 泰拳警告

传送门

糊个柿子吧

\[\sum\limits_{k=0}^n \binom{n}{k}(\frac{p}{p+2})^k(\frac{2}{p+2})^{n-k}\frac{1-\binom{n-k}{\frac{n-k}{2}}(\frac{1}{2})^{n-k}[2\mid n-k]}{2}(k+1) \]

实质上是在考虑平 \(k\) 局的概率及接下来胜局大于败局的概率

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 3000010
#define ll long long
#define reg register int
//#define int long long 

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n;
ll p, invp, fac[N], inv[N], inv2_pow[N];
const ll mod=998244353;
inline void md(ll& a, ll b) {a+=b; a=a>=mod?a-mod:a;}
inline ll qpow(ll a, ll b) {ll ans=1; for (; b; a=a*a%mod, b>>=1) if (b&1) ans=ans*a%mod; return ans;}
inline ll C(int n, int k) {return fac[n]*inv[k]%mod*inv[n-k]%mod;}

namespace force{
	ll ans=0;
	void dfs(int u, int win, int lose, int k, ll pro) {
		if (u>n) {
			if (win>lose) ans=(ans+pro*(k+1)%mod)%mod;
			return ;
		}
		dfs(u+1, win+1, lose, k, pro*invp%mod);
		dfs(u+1, win, lose+1, k, pro*invp%mod);
		dfs(u+1, win, lose, k+1, pro*p%mod*invp%mod);
	}
	void solve() {
		dfs(1, 0, 0, 0, 1);
		printf("%lld\n", ans);
		exit(0);
	}
}

namespace task1{
	ll ans;
	void solve() {
		ll pro, rest;
		for (reg k=0,t; k<=n; ++k) {
			//cout<<k<<endl;
			pro=C(n, k)*qpow(p*invp%mod, k)%mod*qpow(2ll*invp%mod, n-k)%mod;
			t=n-k;
			if (t&1) rest=1ll;
			else rest=1ll-(C(t, t/2)*qpow(inv[2], t)%mod);
			rest=rest*inv[2]%mod;
			ans=(ans+1ll*pro*rest%mod*(k+1)%mod)%mod;
			//cout<<"ans: "<<ans<<endl;
		}
		printf("%lld\n", (ans%mod+mod)%mod);
		exit(0);
	}
}

namespace task2{
	ll ans;
	void solve() {
		const ll inv_2invp=qpow(2ll*invp%mod, mod-2), p_invp=p*invp%mod;
		ll pro, rest, pow1=1, pow2=qpow(2*invp%mod, n);
		for (reg k=0,t; k<=n; ++k) {
			//cout<<k<<endl;
			pro=C(n, k)*pow1%mod*pow2%mod;
			pow1=pow1*p_invp%mod;
			pow2=pow2*inv_2invp%mod;
			t=n-k;
			rest=1ll-((t&1)?0ll:(C(t, t/2)*inv2_pow[t]%mod));
			rest=rest*inv[2]%mod;
			ans=(ans+pro*rest%mod*(k+1)%mod)%mod;
			//cout<<"ans: "<<ans<<endl;
		}
		printf("%lld\n", (ans%mod+mod)%mod);
		exit(0);
	}
}

signed main()
{
	freopen("fight.in", "r", stdin);
	freopen("fight.out", "w", stdout);
	
	n=read(); p=read(); invp=qpow(p+2, mod-2);
	int lim=max(2, n);
	fac[0]=fac[1]=1; inv[0]=inv[1]=1; inv2_pow[0]=1;
	for (reg i=2; i<=lim; ++i) fac[i]=fac[i-1]*i%mod;
	for (reg i=2; i<=lim; ++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	for (reg i=2; i<=lim; ++i) inv[i]=inv[i-1]*inv[i]%mod;
	for (reg i=1; i<=lim; ++i) inv2_pow[i]=inv2_pow[i-1]*inv[2]%mod;
	//force::solve();
	task2::solve();
	
	return 0;
}
posted @ 2021-09-13 05:59  Administrator-09  阅读(18)  评论(0编辑  收藏  举报