题目传送门

题目大意

有一个初始为 \(p\) 的数,每次操作分为以下两个:

  • 有 \(\frac{1}{m+1}\) 的概率$+1,但是中途 \(p\) 的最大值只能为 \(n\)$

  • 有 \(k\) 次减少操作,每次有 \(\frac{1}{m+1}\) 的概率 \(-1\)。

(每次先操作操作 \(1\) 然后操作操作 \(2\))

问 \(p\) 变为 \(0\) 的期望操作次数。

有 \(T\) 次询问,每次保证 \(1\le p\le n\le 1500,m,k\le 10^9\),答案对 \(10^9+7\) 取模。

思路

其实这道题很水,也不知道怎么评到黑题的。

首先,我们可以发现,\(k\) 次被打中 \(i\) 次的概率为 \(\frac{\binom{k}{i}m^{k-i}}{(m+1)^k}\) ,也就是说我们可以算出一次操作由 \(i\) 变为 \(j\) 的概率,我们假设这个为 \(p_{i,j}\)。

然后我们发现肯定可以设 \(f_i\) 表示当前值为 \(i\) 的剩余期望操作次数,我们可以得到转移式:

\[f_i=\sum_{j=0}^{i+1}p_{i,j}\times f_j+1
\]
\[\Rightarrow f_{i+1}=\frac{1}{p_{i,i+1}}(f_i-1-\sum_{j=0}^{i}p_{i,j}\times f_j)
\]

然后你发现这个东西可以用一个套路做了,就是说我们发现每一个 \(f_i\) 我们都可以表示为 \(a\times f_1+b\) 的形式,然后我们递推一下解个方程就可以求出 \(f_1\) 继而求出答案了。

时间复杂度 \(\Theta(Tn\log n)\)。

\(\texttt{Code}\)

#include <bits/stdc++.h>
using namespace std; #define Int register int
#define mod 1000000007
#define MAXN 1505 template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');} int mul (int a,int b){return 1ll * a * b % mod;}
int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
int qkpow (int a,int b){
int res = 1;for (;b;b >>= 1,a = mul (a,a)) if (b & 1) res = mul (res,a);
return res;
}
int inv (int x){return qkpow (x,mod - 2);} int n,m,k,st,invx,invm,ci[MAXN],binom[MAXN]; int calc (int x){//计算k轮中减少x的概率
if (x < 0 || x > k) return 0;
else return mul (binom[x],mul (ci[x],invx));
} int pro (int i,int j){
if (i == n) return calc (i - j);
else return add (mul (calc (i - j),dec (1,invm)),mul (calc (i - j + 1),invm));
} struct node{
int k,b;//表示为k*f[1]+b
node (){}
node (int _k,int _b){k = _k,b = _b;}
node operator + (int x){return node (k,add (b,x));}
node operator - (int x){return node (k,dec (b,x));}
node operator * (int x){return node (mul (k,x),mul (b,x));}
node operator + (node x){return node (add (k,x.k),add (b,x.b));}
node operator - (node x){return node (dec (k,x.k),dec (b,x.b));}
}f[MAXN]; signed main(){
int T;read (T);
while (T --> 0){
read (n,st,m,k),invx = inv (qkpow (m + 1,k)),invm = inv (m + 1);
if (!k){puts ("-1");continue;}
if (!m){
if (k == 1) puts ("-1");
else{
int cnt = 0;
while (st > 0) cnt ++,st = min (n,st + 1) - k;
write (cnt),putchar ('\n');
}
continue;
}
binom[0] = 1;for (Int i = 1;i <= n;++ i) binom[i] = mul (binom[i - 1],mul (k - i + 1,inv (i)));
for (Int i = 0;i <= n && i <= k;++ i) ci[i] = qkpow (m,k - i);
f[1] = node (1,0);
for (Int i = 1;i <= n - 1;++ i){
f[i + 1] = node (0,0);
for (Int j = 1;j <= i;++ j) f[i + 1] = f[i + 1] + f[j] * pro (i,j);
f[i + 1] = (f[i] - 1 - f[i + 1]) * inv (pro (i,i + 1));
}
node sum = node (0,0);
for (Int i = 1;i <= n;++ i) sum = sum + f[i] * pro (n,i);
sum = f[n] - 1 - sum;int f1 = mul (mod - sum.b,inv (sum.k));
write (add (f[st].b,mul (f1,f[st].k))),putchar ('\n');
}
return 0;
}

题解 「BJOI2018 治疗之雨」的更多相关文章

  1. 【BZOJ5292】[BJOI2018]治疗之雨(高斯消元)

    [BZOJ5292][BJOI2018]治疗之雨(高斯消元) 题面 BZOJ 洛谷 题解 设\(f[i]\)表示剩余\(i\)点生命时的期望死亡的次数. 考虑打\(k\)次下来脸上被打了\(i\)下的 ...

  2. BZOJ5292 & 洛谷4457 & LOJ2513:[BJOI2018]治疗之雨——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5292 https://www.luogu.org/problemnew/show/P4457 ht ...

  3. 洛谷P4457/loj#2513 [BJOI2018]治疗之雨(高斯消元+概率期望)

    题面 传送门(loj) 传送门(洛谷) 题解 模拟赛的时候只想出了高斯消元然后死活不知道怎么继续--结果正解居然就是高斯消元卡常? 首先有个比较难受的地方是它一个回合可能不止扣一滴血--我们得算出\( ...

  4. [BZOJ5292][BJOI2018]治疗之雨(概率DP+高斯消元)

    https://blog.csdn.net/xyz32768/article/details/83217209 不难找到DP方程与辅助DP方程,发现DP方程具有后效性,于是高斯消元即可. 但朴素消元显 ...

  5. luoguP4457 [BJOI2018]治疗之雨 概率期望 + 高斯消元

    应该是最后一道紫色的概率了....然而颜色啥也代表不了.... 首先看懂题意: 你现在有$p$点体力,你的体力上限为$n$ 在一轮中, 1.如果你的体力没有满,你有$\frac{1}{m + 1}$的 ...

  6. [BJOI2018]治疗之雨

    题目 我还没疯 发现如果我们将血量抽象成点,一轮操作抽象成图上的一条边,我们如果能求出每一条边的概率,我们就能搞一下这道题 假设我们求出了这个图\(E\),设\(dp_i\)表示从\(i\)点到达\( ...

  7. [BZOJ5292] [BJOI2018]治疗之雨

    题目链接 BZOJ:https://lydsy.com/JudgeOnline/problem.php?id=5292 洛谷:https://www.luogu.org/problemnew/show ...

  8. 题解 「BZOJ4919 Lydsy1706月赛」大根堆

    题目传送门 题目大意 给出一个 \(n\) 个点的树,每个点有权值,从中选出一些点,使得满足大根堆的性质.(即一个点的祖先节点如果选了那么该点的祖先节点的权值一定需要大于该点权值) 问能选出来的大根堆 ...

  9. 「BJOI2018」链上二次求和

    「BJOI2018」链上二次求和 https://loj.ac/problem/2512 我说今天上午写博客吧.怕自己写一上午,就决定先写道题. 然后我就调了一上午线段树. 花了2h找到lazy标记没 ...

随机推荐

  1. rabbitMq内存与磁盘分配问题

    在服务器上也可以改变配置文件修改内存 也可以使用命令进行分配: 相对内存:rabbitmqctl  set_vm_memory_hgih_waterwmark 0.4     使用时可以把这个0.4替 ...

  2. ES6对象扩展——部分新的方法和属性

    1.Object.is方法返回布尔值,和全等于===差不多,除了参数是+0和-0,以及NaN时 //Object.is,返回布尔值,和全等于===差不多,除了+0和-0,以及NaN console.l ...

  3. 一文彻底弄懂this关键字用法

    哈喽,大家好,我是指北君. 介绍完 native.static.final 关键字后,指北君再接再厉,接着为大家介绍另一个常用的关键字--this. this 也是Java中的一个关键字,在<J ...

  4. Swift-Button 的 highlighted(高亮)

    摘要 在学习小程序时,看到小程序中的一个样式属性 hover-class,通过设置这个属性,就可以给点击的控件添加一个高亮效果.所以也就萌生了在 Swift 也实现一个类似的功能的想法,开干. 下面代 ...

  5. 快速入门PaddleOCR,并试用其开发一个搜题小工具

    介绍 PaddleOCR 是一个基于百度飞桨的OCR工具库,包含总模型仅8.6M的超轻量级中文OCR,单模型支持中英文数字组合识别.竖排文本识别.长文本识别.同时支持多种文本检测.文本识别的训练算法. ...

  6. AWS使用ALB负载均衡遇到的问题

    文章原文 问题描述 ALB 负载均衡 RGC-Dev-ALB.xxx.cn-north-1.elb.amazonaws.com.cn 解析到2个IP 54.223.xxx.xx和52.81.xxx.x ...

  7. 再见了,我的散装研发管理平台;再见了,4台ECS!

    周末的时候,收到好几个云服务器临近过期的通知短信,准备续个费,居然都要大几千!因为这几个都是以前低价抢购的,掐指一算,如果都续费的话,要蚕食好多利润!作为一名自己养活自己的独立开发者,节省成本是必备技 ...

  8. SciPy笔记

    一.简介 SciPy 是一个开源的 Python 算法库和数学工具包.Scipy 是基于 Numpy 的科学计算库,用于数学.科学.工程学等领域,很多有一些高阶抽象和物理模型需要使用 Scipy.Sc ...

  9. Redis集群的搭建及与SpringBoot的整合

    1.概述 之前聊了Redis的哨兵模式,哨兵模式解决了读的并发问题,也解决了Master节点单点的问题. 但随着系统越来越庞大,缓存的数据越来越多,服务器的内存容量又成了问题,需要水平扩容,此时哨兵模 ...

  10. RSTP

    一.STP协议的缺点,存在的问题 STP 协议工作时间收敛慢,响应时间长---------->RSTP 原始的802.1d(stp)不支持多个vlan---->(PVST===>把一 ...