题解

具体就是列一个未知数方程\(dp[i]\)表示有\(i\)滴血的时候期望多少轮

\(dp[i] = 1 + \sum_{j = 1}^{i + 1} a_{i,j}dp[j]\)

\(dp[n] = 1 + \sum_{j = 1}^{n} a_{i,j}dp[j]\)

\(a_{i,j}\)表示从\(i\)滴血到\(j\)滴血的概率

可以高斯消元?

但是发现这个似乎和递推形式只差一点点

\(a_{i,i + 1} dp[i + 1] = -1 - \sum_{j = 1}^{i - 1} a_{i,j}dp[j] + (1 - a_{i,i})dp[i]\)

但是我们不知道\(dp[1]\)

我们可以把\(dp[1]\)设成\(X\),然后用前\(n - 1\)个式子推出来\(dp[n] = A_1x + B_1\)

用第\(n\)个式子再推出来\(dp[n] = A_2x + B_2\)就可以解出来\(x\)了

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define MAXN 20005
#define eps 1e-8
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 1000000007;
int C[1505],N,M,P,K;
pii dp[1505];
int g[1505],f[1505],d[1505],inv[1505],ad[1505];
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
int fpow(int x,int c) {
int res = 1,t = x;
while(c) {
if(c & 1) res = mul(res,t);
t = mul(t,t);
c >>= 1;
}
return res;
}
const pii operator + (const pii &a,const pii &b) {
return mp(inc(a.fi,b.fi),inc(a.se,b.se));
}
const pii operator * (const pii &a,const int &d) {
return mp(mul(a.fi,d),mul(a.se,d));
}
void update(pii &a,pii b) {
a = a + b;
}
void Solve() {
read(N);read(P);read(M);read(K);
if(K == 0) {puts("-1");return;}
if(M == 0) {
if(K == 1) {
puts("-1");
}
else {
int cnt = 0;
if(P == N) {P = max(0,P - K);++cnt;}
if(P) cnt += (P - 1) / (K - 1) + 1;
out(cnt);enter;
}
return;
} int T = min(N,K);
int InvM = fpow(M,MOD - 2),InvM1 = fpow(M + 1,MOD - 2);
C[0] = 1;C[1] = K;
g[0] = 1;f[0] = fpow(mul(InvM1,M),K);int t = mul(InvM,M + 1);
g[1] = InvM1,f[1] = mul(f[0],t);
for(int i = 2 ; i <= T ; ++i) {
C[i] = mul(C[i - 1],mul(inv[i],inc(K,MOD - i + 1)));
g[i] = mul(g[i - 1],g[1]);
f[i] = mul(f[i - 1],t);
}
for(int i = 0 ; i <= T ; ++i) {
t = mul(C[i],mul(g[i],f[i]));
d[i] = mul(t,mul(M,InvM1));
ad[i] = mul(t,InvM1);
}
for(int i = T + 1 ; i <= N ; ++i) d[i] = ad[i] = 0;
dp[1] = mp(1,0);
for(int i = 2 ; i <= N ; ++i) {
dp[i] = mp(0,MOD - 1);
update(dp[i],dp[i - 1] * inc(1,MOD - inc(d[0],ad[1])));
for(int j = 1 ; j < i - 1; ++j) {
update(dp[i],dp[j] * (MOD - inc(d[i - 1 - j],ad[i - j])));
}
dp[i] = dp[i] * fpow(ad[0],MOD - 2);
}
pii another = mp(0,1);
for(int i = 1 ; i < N ; ++i) {
if(N - i <= T) {
t = mul(C[N - i],mul(g[N - i],f[N - i]));
update(another,dp[i] * t);
}
}
another = another * fpow(inc(1,MOD - f[0]),MOD - 2);
if(another.fi == dp[N].fi) {puts("-1");return;}
int x = mul(inc(dp[N].se,MOD - another.se),fpow(inc(another.fi,MOD - dp[N].fi),MOD - 2));
out(inc(mul(dp[P].fi,x),dp[P].se));enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
inv[1] = 1;
for(int i = 2 ; i <= 1500 ; ++i) {
inv[i] = mul(inv[MOD % i],MOD - MOD / i);
}
int T;read(T);
while(T--) Solve();
return 0;
}

【LOJ】#2513. 「BJOI2018」治疗之雨的更多相关文章

  1. 「BJOI2018」治疗之雨

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

  2. 【LOJ2513】「BJOI2018」治疗之雨

    题意 你现在有 \(m+1\) 个数:第一个为 \(p\) ,最小值为 \(0\) ,最大值为 \(n\) :剩下 \(m\) 个都是无穷,没有最小值或最大值.你可以进行任意多轮操作,每轮操作如下: ...

  3. LOJ #6436. 「PKUSC2018」神仙的游戏(字符串+NTT)

    题面 LOJ #6436. 「PKUSC2018」神仙的游戏 题解 参考 yyb 的口中的长郡最强选手 租酥雨大佬的博客 ... 一开始以为 通配符匹配 就是类似于 BZOJ 4259: 残缺的字符串 ...

  4. 「BJOI2018」链上二次求和

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

  5. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  6. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  7. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  8. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  9. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

随机推荐

  1. 学习Spring Boot:(十九)Shiro 中使用缓存

    前言 在 shiro 中每次去拦截请求进行权限认证的时候,都会去数据库查询该用户的所有权限信息, 这个时候就是有一个问题了,因为用户的权限信息在短时间内是不可变的,每次查询出来的数据其实都是重复数据, ...

  2. PHP使用serialize和json_encode序列化数据并通过redis缓存文件和$GLOGALS缓存资源对象

    PHP常用缓存方式:第一种,把需要缓存的数据进行处理,形成PHP可以直接执行的文件.在需要缓存数据的时候,通过include方式引入,并使用.第二种,把需要的数据通过serialize函数序列化后直接 ...

  3. Luogu2661 信息传递(图论)

    Luogu2661 信息传递(图论) Description 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti ...

  4. Ubantu里面的Sublime Text3不支持中文的解决办法

    参考的大佬链接:https://github.com/lyfeyaj/sublime-text-imfix 更新然后将系统升级到最新版本,在linux终端输入 sudo apt-get update ...

  5. 转:iOS-生成Bundle包-引入bundle-使用bundle

    在我们使用第三方框架时,常常看到XXX.bundle的文件. 我们找到该文件,显示包内容,大致看到很多资源文件:图片.配置文本.XIB文件……   什么是Bundle文件? 简单理解,就是资源文件包. ...

  6. Hadoop Yarn源码 - day2

    接着昨天的继续看hadoop-yarn-api,昨天看了api package下的4个协议,今天来看下con package下的代码 conf目录下的内容比较少,就4个文件分别是Configurati ...

  7. spark DataFrame 常见操作

    spark dataframe派生于RDD类,但是提供了非常强大的数据操作功能.当然主要对类SQL的支持. 在实际工作中会遇到这样的情况,主要是会进行两个数据集的筛选.合并,重新入库. 首先加载数据集 ...

  8. Flex 数组问题!

    设计一个图形类,来对应一个图形! 这个类大概的代码是: public class ShapeModel extends ... { [bindable] private var _x:Number = ...

  9. 【问题收集·知识储备】Xcode只能选择My Mac,不能选择模拟器如何解决?

      网友问题:请问打开一个应用,只能选择My Mac,不能选择模拟器如何解决? 答案:             下面将问答过程记录如下:     CHENYILONG Blog 请问打开一个应用,只能 ...

  10. 由于找不到MSVCP20.dll,无法继续执行代码

    系统:win10 专业版,刚升级win10没几天 mysql 5.7.21 解压安装,初始化时报错,错误如图: 一.查找错误原因 参考:MySQL安装使用遇到的问题, 找到微软中文官方网站,搜索 ms ...