牛客多校第十场

H Wheel of Fortune

题意:

给定两个英雄的血量和双方七个随从的血量,此时尤格萨隆释放命运之轮,随机释放炎爆术直至一分死亡。求获胜的概率。

思路:

发现不管是敌方随从还是己方随从只能挡子弹,对游戏获胜没有影响。 这时只需要考虑英雄血量,获胜概率是由全砸对面脸的概率,到砸自己脸到10一下对面死亡的。对面需要被砸死,砸死次数bb=B10\lceil \frac{B} {10}\rceil,自己被砸死需要aa=A10\lceil \frac{A} {10}\rceil次,获胜的可能有砸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;
}
全部评论

相关推荐

头像
04-09 14:29
Java
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务