题目链接

BZOJ:https://lydsy.com/JudgeOnline/problem.php?id=5292

洛谷:https://www.luogu.org/problemnew/show/P4457

LOJ:https://loj.ac/problem/2513

Solution

神仙期望题(可能是我期望太差了QAQ)

这题看懂题可能占了\(50\%\)的难度....

题目中的最大值最小值指的是上限和下限,我就是因为这个懵了好久...那么容易发现其他的怪你\(A\)多少下或者奶多少下都没有问题,我们只需要考虑自己就好了。

设\(p_i\)表示一个回合对自己造成\(i\)点伤害的概率,这里不考虑自己的上下界,那么显然可以得到:

\[p_i=\dfrac{\binom{k}{i}m^{k-i}}{(m+1)^k}
\]

分母是总情况,分子组合数表示哪些攻击到自己,剩下的随便选。

设\(f_i\)表示答案,即自己有\(i\)滴血可以存活回合数的期望,那么仔细想想可以得到一个这样的式子:

\[f_i=\frac{m}{m+1}\left(\sum_{j=i}^{n}p_j+\sum_{j=0}^{i-1}p_j(f_{i-j}+1) \right)+\frac{1}{m+1}\left(\sum_{j=i+1}^{n}p_j+\sum_{j=0}^ip_j(f_{i+1-j}-1)\right)
\]

前半部分算的是自己没被奶,括号内的\(\sum_{j=i}^np_j\)表示的是自己这回合被\(A\)死了,那么一定要\(A\) \(i\)次或以上,然后回合数为\(1\),乘起来就是这个,后面部分表示自己没被\(A\)死,那么回合数就是\(f_{i-j}+1\),\(+1\)是因为要算上本回合。

后半部分算的是自己被奶了,和前面差不多。

把式子画一下,\((f_{i-j}+1)\)这个括号展开,由于:

\[\sum_{i=0}^{n}p_i=1
\]

这个可以根据定义得到。

然后把式子展开:

\[f_i=\frac{m}{m+1}\left(1+\sum_{j=0}^{i-1}p_jf_{i-j} \right)+\frac{1}{m+1}\left(1+\sum_{j=0}^ip_jf_{i+1-j}\right)
\]

\[f_i=1+\frac{m}{m+1}\sum_{j=0}^{i-1}p_jf_{i-j}+\frac{1}{m+1}\sum_{j=0}^ip_jf_{i+1-j}
\]

注意下边界条件,因为满血不能被奶,所以:

\[f_n=1+\sum_{i=0}^{n-1}p_if_{n-i}
\]

那么我们得到了一堆的方程,至此我们可以\(O(Tn^3)\)的高斯消元解决。

但是这并不足以通过本题,我们观察一下高斯消元列出来的矩阵,大概长这样:

\[\begin{bmatrix}
a_{1,1}&a_{1,2}&0&0&\cdots&0\\
a_{2,1}&a_{2,2}&a_{2,3}&0&\cdots&0\\
a_{3,1}&a_{3,2}&a_{3,3}&a_{3,4}&\cdots&0\\
\vdots&\vdots&\vdots&\vdots&\ddots&\vdots\\
a_{n-2,1}&a_{n-2,2}&a_{n-2,3}&a_{n-2,4}&\cdots&a_{n-2,n}\\
a_{n-1,1}&a_{n-1,2}&a_{n-1,3}&a_{n-1,4}&\cdots&a_{n-1,n}\\
a_{n,1}&a_{n,2}&a_{n,3}&a_{n,4}&\cdots&a_{n,n}\\
\end{bmatrix}
\]

总之就是主对角线左边是满的,右边有一格有值。

那么我们高斯消元的时候每次只会对三个值造成影响,那么复杂度就降为\(O(Tn^2)\),足以通过此题。

#include<bits/stdc++.h>
using namespace std; void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
} void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf double
#define ll long long const int maxn = 1.5e3+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7; int n,P,k,m,p[maxn],inv[maxn],fac[maxn],ifac[maxn],a[maxn][maxn],im; int add(int x,int y) {return x+y>mod?x+y-mod:x+y;}
int del(int x,int y) {return x-y<0?x-y+mod:x-y;}
int mul(int x,int y) {return 1ll*x*y-1ll*x*y/mod*mod;} int qpow(int aa,int x) {
int res=1;
for(;x;x>>=1,aa=mul(aa,aa)) if(x&1) res=mul(res,aa);
return res;
} void solve() {
read(n),read(P),read(m),read(k);im=qpow(m+1,mod-2);
if(k==0) return puts("-1"),void();
if(m==0) {
if(k==1) puts("-1");
else {int res=0;for(;P>0;) {if(P<n) P++;P-=k;res++;}write(res);}return ;
}
inv[0]=inv[1]=1;for(int i=2;i<=n;i++) inv[i]=mul(mod-mod/i,inv[mod%i]);
fac[0]=1;for(int i=1;i<=n;i++) fac[i]=mul(fac[i-1],i);
ifac[0]=1;for(int i=1;i<=n;i++) ifac[i]=mul(ifac[i-1],inv[i]);
p[0]=mul(qpow(m,k),qpow(qpow(m+1,k),mod-2));
for(int i=1;i<=n;i++) p[i]=mul(mul(p[i-1],mul(i>k?0:k-i+1,inv[i])),qpow(m,mod-2)); for(int i=1;i<n;i++) {
a[i][n+1]=a[i][i]=mod-1;
for(int j=0;j<i;j++) a[i][i-j]=add(a[i][i-j],mul(mul(im,m),p[j]));
for(int j=0;j<=i;j++) a[i][i+1-j]=add(a[i][i+1-j],mul(im,p[j]));
}a[n][n+1]=a[n][n]=mod-1;
for(int i=0;i<n;i++) a[n][n-i]=add(a[n][n-i],p[i]); a[1][2]=mul(a[1][2],qpow(a[1][1],mod-2));
if(n!=1) a[1][n+1]=mul(a[1][n+1],qpow(a[1][1],mod-2));
a[1][1]=1; for(int i=2;i<=n;i++) {
for(int j=1;j<i;j++) {
if(!a[i][j]) continue;
a[i][j+1]=del(a[i][j+1],mul(a[j][j+1],a[i][j]));
a[i][n+1]=del(a[i][n+1],mul(a[j][n+1],a[i][j]));
a[i][j]=0;
}
a[i][i+1]=mul(a[i][i+1],qpow(a[i][i],mod-2));
if(i!=n) a[i][n+1]=mul(a[i][n+1],qpow(a[i][i],mod-2));
a[i][i]=1;
} for(int i=n-1;i;i--) a[i][n+1]=del(a[i][n+1],mul(a[i+1][n+1],a[i][i+1]));
write(a[P][n+1]); for(int i=1;i<=n;i++) a[i][i]=a[i][i+1]=a[i][n+1]=0;
} int main() {
int t;read(t);while(t--) solve();
return 0;
}

[BZOJ5292] [BJOI2018]治疗之雨的更多相关文章

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

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

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

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

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

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

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

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

  5. [BJOI2018]治疗之雨

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

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

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

  7. 题解 「BJOI2018 治疗之雨」

    题目传送门 题目大意 有一个初始为 \(p\) 的数,每次操作分为以下两个: 有 \(\frac{1}{m+1}\) 的概率$+1,但是中途 \(p\) 的最大值只能为 \(n\)$ 有 \(k\) ...

  8. 【LOJ】#2513. 「BJOI2018」治疗之雨

    题解 具体就是列一个未知数方程\(dp[i]\)表示有\(i\)滴血的时候期望多少轮 \(dp[i] = 1 + \sum_{j = 1}^{i + 1} a_{i,j}dp[j]\) \(dp[n] ...

  9. 「BJOI2018」治疗之雨

    传送门 Description 有\(m+1\)个数,第一个数为\(p\),每轮:选一个数\(+1\),再依次选\(k\)个数\(-1\) 要求如果第一个数\(=N\),不能选它\(+1\),如果第一 ...

随机推荐

  1. 天嵌IMX6开发板测试-第一篇

    1.看下开发板介绍 品牌: 天嵌 CPU型号: NXP i.MX6Q 架构: Cortex_A9 主频: *1GHz 内存: 2GB DDR3 存储: 8GB eMMC FLA(64GB可扩) 2. ...

  2. 无法嵌入互操作类型“ADOX.CatalogClass”。请改用适用的接口。

    编译环境:vs2013 系统报错:无法嵌入互操作类型"ADOX.CatalogClass".请改用适用的接口. 解决方法:选中项目中引入的dll(本例中为Microsoft ADO ...

  3. Python中安装Prophet

    1. 先安装pystan依赖 按照https://pystan.readthedocs.io/en/latest/windows.html说明,请使用如下命令 conda install libpyt ...

  4. Qt-QML-给我的导航条写一个动画-State-Transition

    上篇中,我已经写出一个导航条的,虽然太丑了,不过功能是有了,这次我将要给我的导航条加一个动画,先看下演示效果 这次我是用的是一个状态动画,大致原理就是写出一个空间的几个状态,完了再加一个过度动画,这里 ...

  5. MySQL连接本地数据库时报1045错误的解决方法

     navicat for MySQL 连接本地数据库出现1045错误 如下图:  说明连接mysql时数据库密码错误,需要修改密码后才可解决问题: 解决步骤如下: .首先打开命令行:开始->运行 ...

  6. TW实习日记:第23天

    主要的项目已经在修改一些细节以提高用户体验的阶段了,所以并不是太忙,主要就是对样式和一些细节修修改改.然后下午帮助同事的新项目做了一个功能点,主要就是调通接口就行,因为参数巨多,所以总要和网端那边的后 ...

  7. lintcode12 带最小值操作的栈

    实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值. 你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成. 建一个栈helpStack,用来存放从 ...

  8. 通过流的方式操作hadoop的API

    通过流的方式操作hadoop的API 功能: 可以直接用来操作hadoop的文件系统 可以用在mapreduce的outputformat中设置RecordWrite 参考: 概念理解 http:// ...

  9. 【第四章】Shell 条件测试表达式

    shell中条件测试的三种格式: 格式1: test 条件表达式格式2: [ 条件表达式 ]格式3: [[ 条件表达式 ]] 使用test: [root@host- ~]# test -f file ...

  10. 剑指offer-二叉树搜索树与双向链表25

    题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. class Solution: def Convert(self, pRo ...