题目传送门

题目大意

有一个初始为 \(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. ubuntu下安装teamiewer

    下载地址: https://download.teamviewer.com/download/linux/teamviewer_amd64.deb 如果无法下载,则在https://www.teamv ...

  2. jQuery mobile网格布局

    3.4 内容格式化 jQuery Mobile中提供了许多非常有用的工具与组件,如多列的网格布局.折叠形的面板控制等,这些组件可以帮助开发者快速实现正文区域内容的格式化. 3.4.1 网格布局 jQu ...

  3. Vulnhub靶机渗透 -- DC5

    信息收集 通过nmap搜索到IP为:192.168.200.11 开启了80http.111RPC服务端口 先打开网页,然后进行目录爆破 contact.php 攻击 经搜索没有发现可以攻击wheel ...

  4. MySQL(二)——常用命令

    一.MySQL服务器1.介绍安装服务:mysqld -install停止服务:net stop mysql启动服务:net start mysql用户名:root,密码:Password,连接数据库: ...

  5. Django的模板文件的路径设置

    TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS' ...

  6. Onenote实现OCR识别图片

    OCR识别推荐两个软件: 1.       Tesseract:一个开源的,由谷歌维护的OCR软件. 2.       Onenote:微软Office附带或者可以自己独立安装. 3.       O ...

  7. GIS常用算法

    目录 1.常用算法 1.1.计算两经纬度点之间的距离 1.2.根据已知线段以及到起点距离,求目标点坐标 1.3.已知点.线段,求垂足 1.4.线段上距离目标点最近的点 1.5.点缓冲 1.6.点和面关 ...

  8. Wpf读写Xaml文件

    前言 本文主要介绍Wpf读写Xaml文件. 读写实现 首先我们使用XamlWriter将Wpf的对象转换为Xaml字符串,代码如下: var btn = sender as Button; strin ...

  9. js简单化技巧

    1.交换两个变量而没有第三个 let x = 1;let y = 2;[x, y] = [y, x];console.log(x, y); 输出: 2 1 2.将数字转换为字符串 const num  ...

  10. UVA 506 System Dependencies(模拟 烂题)

    https://vjudge.net/problem/UVA-506 题目是给出了五种指令,DEPEND.INSTALL.REMOVE.LIST.END,操作的格式及功能如下: DEPEND item ...