牛客多校第十场
H Wheel of Fortune
题意:
给定两个英雄的血量和双方七个随从的血量,此时尤格萨隆释放命运之轮,随机释放炎爆术直至一分死亡。求获胜的概率。
思路:
发现不管是敌方随从还是己方随从只能挡子弹,对游戏获胜没有影响。 这时只需要考虑英雄血量,获胜概率是由全砸对面脸的概率,到砸自己脸到10一下对面死亡的。对面需要被砸死,砸死次数=,自己被砸死需要=次,获胜的可能有砸b,b+1,···,b+a-1次,可以看作a被砸到的时候插到b次对面被砸到的时候。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 998244353;
const int N = 1e7+10;
ll x,a[10],y,b[10],f[N],g[N];
ll qk(ll a,ll b){
ll ans=1;
a%=mod;
b%=mod;
while(b){
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
b%=mod;
}
return ans;
}
ll inv(ll a){//逆元
return qk(a,mod-2);
}
ll C(ll a, ll b) // 通过定义求组合数C(a, b),乘法逆元
{
if (a < b) return 0;
ll x = 1, y = 1; // x是分子,y是分母
for (ll i = a, j = 1; j <= b; i --, j ++ )
{
x = (ll)x * i % mod;
y = (ll) y * j % mod;
}
return x * (ll)qk(y, mod - 2) % mod;
}
ll lucas(ll a, ll b)
{
if (a < mod && b < mod) return C(a, b);
return (ll)C(a%mod, b % mod) * lucas(a / mod, b / mod) % mod;
}
int main(){
scanf("%lld",&x);
for(int i=1;i<=7;i++) scanf("%lld",&a[i]);
scanf("%lld",&y);
for(int i=1;i<=7;i++) scanf("%lld",&b[i]);
if(x==y) {
printf("499122177\n");
}
else{
ll u=ceil(x/10.0),v=ceil(y/10.0);
ll p=inv(qk(2,v));
ll q=1ll;
ll t=v,tt=2;
for(ll i=1;i<=u-1;i++){
ll num=t*inv(tt)%mod;
t=(t*(v+i)%mod*inv(i+1))%mod;
tt=tt*2%mod;
q=(q+num)%mod;
}
ll ans=p*q%mod;
printf("%lld\n",ans);
}
return 0;
}