题目传送门

题目大意

有一个初始为 \(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. jwt《token》

    payload与claims只能存在一个这部分是jwt源码:依赖如下:官方文档的依赖 <dependency> <groupId>io.jsonwebtoken</gro ...

  2. Cookie及通过Cookie常见应用

    会话的概念 会话可以简单理解为:用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 会话需要解决的问题 每个用户与服务器进行交互的过程中,各自会有一 ...

  3. Android手机 自动批量发朋友圈

    做了各种对比之后,还是这个微商工具最好用

  4. Spring系列之JDBC对不同数据库异常如何抽象的?

    前言 使用Spring-Jdbc的情况下,在有些场景中,我们需要根据数据库报的异常类型的不同,来编写我们的业务代码.比如说,我们有这样一段逻辑,如果我们新插入的记录,存在唯一约束冲突,就会返回给客户端 ...

  5. ASH数据的迁移:导出导入

    自己写的小工具: 查看帮助 [oracle@redhat76 2]$ ./orash Usage: sh orash keyword [value1] [value2] --------------- ...

  6. 20210805 noip31

    考场 没有一眼题 T1 想到先贪心地算出最大得分,任意构造出一种方案,不断调整以增大字典序. T2 发现在 \(x_k\) 确定的情况下操作次数就是左右两边的逆序对数,\(x_i\) 互不相同时直接找 ...

  7. noip模拟18

    \(\color{white}{\mathbb{曲径通幽,星汉隐约,缥缈灯影,朦胧缺月,名之以:薄雾}}\) 放眼望去前十被我弃掉的 \(t2\) 基本都上85了-- 开考就以为 \(t2\) 是个大 ...

  8. Tars | 第5篇 基于TarsGo Subset路由规则的Java JDK实现方式(上)

    目录 前言 1. 修改.tars协议文件 1.1 Go语言修改部分 1.2 修改地方的逻辑 1.3 通过协议文件自动生成代码 2. [核心]增添Subset核心功能 2.1 Go语言修改部分 2.2 ...

  9. Git - Mac 电脑使用 brew 更新 Git

    安装 Homebrew Homebrew 是一个软件包管理器.它的作用就是将软件包安装到自己的目录中,然后将其文件符号链接到 /usr/local.更多信息,请自行进入官网查看 https://bre ...

  10. Delphi使用AcroPDF ActiveX显示PDF文件

    效果展示 调用方式 放入窗体即可使用,不想安装太多组件,可使用纯代码方式调用 interface ..... var AcroPDF: TAcroPDF; .... implementation .. ...