• HDU6656——Kejin Player(期望DP+前缀和)


    原题链接
    题意:
    在这里插入图片描述
    思路:
    因为只能一级级的升级,所以要升级到r级一定会先升级到l级。
    dp[i]表示从1升到i级的花费,那么对于每次询问dp[r]-dp[l]就是答案(相当于维护一个前缀和)
    状态转移:
    因为每次从i级升到i+1级的成功率是不一定的,所以升级次数也是不一定的。假设第x次时升级到i+1级成功,所以前x-1次都是失败的。
    dp[i+1]=dp[i]+a[i]+(t-1)*(a[i]+dp[i]-dp[x[i]]);
    a[i]表示第x次升级的花费,后面的表示前x-1次的花费,dp[i]-dp[x[i]]表示从x[i]升级到i的花费。
    因为第x次成功,也就是说x次成功了1次,即1/x=r/s;
    注意取模和逆元。
    代码:

    const int maxn=1e6+100;
    int n,q;
    ll r[maxn],s[maxn],x[maxn],a[maxn];
    ll dp[maxn];
    ll ksm(ll a,ll b,ll p)
    {
        ll res=1;
        while(b)
        {
            if(b&1)res=res*a%p;
            a=a*a%p;
            b>>=1;
        }
        return res;
    }
    ll getinv(ll x)
    {
        return ksm(x,mod-2,mod);
    }
    int main()
    {
        int t;scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&q);
            for(int i=1; i<=n; i++)
            {
                scanf("%lld%lld%lld%lld",&r[i],&s[i],&x[i],&a[i]);
                ll invr=getinv(r[i]);
                ll t=s[i]*invr%mod;
                ll t1=(t-1+mod)%mod;
                dp[i+1]=t*((dp[i]+a[i])%mod)%mod;
                dp[i+1]=(dp[i+1]-t1*dp[x[i]]%mod+mod)%mod;
            }
            while(q--)
            {
                int l,r;
                scanf("%d%d",&l,&r);
                printf("%lld
    ",(dp[r]-dp[l]+mod)%mod);
            }
        }
    
        return 0;
    }
    

    参考:

  • 相关阅读:
    webpack基本使用笔记
    gulp学习记录
    页面优化
    linux下使用indent整理代码
    C++中的getline()
    Sum of Two Integers
    TwoSum
    IDEA个人常用快捷键总结
    mysql数据库遇到的各种问题
    Python中*args 和**kwargs的用法和区别
  • 原文地址:https://www.cnblogs.com/OvOq/p/14853086.html
Copyright © 2020-2023  润新知