传送门

Description

有\(m+1\)个数,第一个数为\(p\),每轮:选一个数\(+1\),再依次选\(k\)个数\(-1\)

要求如果第一个数\(=N\),不能选它\(+1\),如果第一个数\(=0\),不能选它\(-1\)

如果没有可选的数,跳过该次选择

问使得第一个数\(=0\)的期望步数

\(N\le1500\),\(Case\le10\)

Solution

设\(f_i\)表示当第一个数为\(i\)时期望多少轮变为\(0\)

\[f_i=1+\sum_{j=1}^{i+1}p_{i,j}f_j,1\le i<n
\\
f_n=1+\sum_{j=1}^np_{i,j}f_j
\]

其中\(p_{i,j}\)表示一轮将第一个数从\(i\)变为\(j\)的概率

对第一个式子进行移项

\[p_{i,i+1}f_{i+1}=-1-\sum_{j=1}^{i-1}f_j+(1-p_{i,i})f_i,2\le i \le n
\]

问题在于不知道\(f_1\),所以可以先把\(f_1\)设为\(x\),推出\(f_n=a_1x+b_1\)

然后根据第二个式子,得到\(f_n=a_1x+b_2\)

最后解出\(f_1\),求得\(f_p\)

Code 

#include<bits/stdc++.h>
#define ll long long
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MN=1505,P=1e9+7;
int Mul(int x,int y){return (1ll*x*y)%P;}
int Add(int x,int y){return (x+y)%P;}
int fp(int x,int y=P-2){int r=1;for(;y;y>>=1,x=Mul(x,x))if(y&1)r=Mul(r,x);return r;}
struct d{
int x,y;
d(int x=0,int y=0):x(x),y(y){}
d operator+(const d&o)const{return d(Add(x,o.x),Add(y,o.y));}
d operator-(const d&o)const{return d(Add(x,P-o.x),Add(y,P-o.y));}
d operator*(const int o)const{return d(Mul(x,o),Mul(y,o));}
}f[MN],or_;
int N,p,M,K,invM_,invM,a[MN][MN],g[MN],b[MN],inv[MN],X;
int solve()
{
reg int i,j;
if(K==0)return -1;
if(M==0)
{
if(K==1&&N>1) return -1;
g[0]=0;for(i=1;i<=N;++i)g[i]=g[max(min(N,i+1)-K,0)]+1;
return g[p];
}
memset(b,0,sizeof b);memset(a,0,sizeof a);
invM_=fp(M+1);invM=fp(M);b[0]=Mul(fp(M,K),fp(invM_,K));
for(i=1;i<=N&&i<=K;++i)b[i]=Mul(Mul(b[i-1],invM),Mul(inv[i],K-i+1));
for(i=1;i<N;++i)for(j=1;j<=i+1;++j)if(i-K<=j)
a[i][j]=Add(Mul(invM_,b[i+1-j]),Mul(invM_,Mul(M,b[i-j])));
for(i=1;i<=N;++i)a[N][i]=b[N-i];
for(f[1]=d(1,0),i=2;i<=N;++i)
{
f[i]=d(0,P-1);
for(j=1;j<i-1;++j)f[i]=f[i]-(f[j]*a[i-1][j]);
f[i]=f[i]+f[i-1]*((1-a[i-1][i-1]+P)%P);
f[i]=f[i]*fp(a[i-1][i]);
}
for(or_=d(0,1),i=1;i<N;++i)or_=or_+f[i]*a[N][i];or_=or_*fp(Add(1,P-a[N][N]));
or_=or_-f[N];if(!or_.x&&f[p].x) return -1;
X=Mul(or_.y,fp(P-or_.x));
return Add(Mul(f[p].x,X),f[p].y);
}
int main()
{
int cas=read();inv[0]=inv[1]=1;
for(int i=2;i<=1500;++i)inv[i]=Mul((P-P/i),inv[P%i]);
while(cas--)
{
N=read(),p=read(),M=read(),K=read();
printf("%d\n",solve());
}
return 0;
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

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

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

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

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

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

  3. 「BJOI2018」链上二次求和

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

  4. 「BJOI2018」求和

    「BJOI2018」求和 传送门 观察到 \(k\) 很小而且模数不会变,所以我们直接预处理 \(k\) 取所有值时树上前缀答案,查询的时候差分一下即可. 参考代码: #include <alg ...

  5. 【LOJ】#2511. 「BJOI2018」双人猜数游戏

    题解 设\(f[p][a][b]\)表示询问了\(p\)次,答案是\(a,b\)是否会被猜出来 然后判断如果\(p = 1\) 第一个问的\(Alice\),那么\([s,\sqrt{nm}]\)约数 ...

  6. 【LOJ】#2493. 「BJOI2018」染色

    题面 题解 推结论大题--然而我推不出什么结论 奇环显然是NO 如果一个联通块里有两个分离的环,也是NO 如果一个联通块里,点数为n,边数为m m <= n的时候,是YES m >= n ...

  7. 【LOJ】#2492. 「BJOI2018」二进制

    题解 每次开这样的数据结构题感想都大概是如下两点 1.为什么别人代码长度都是我的1/2???? 2.为什么我运行时间都是他们的两倍???? 简单分析一下,我们关注一个区间是否合法只关注这个区间有多少个 ...

  8. 【LOJ】#2512. 「BJOI2018」链上二次求和

    题面 题解 转化一下可以变成所有小于等于r的减去小于等于l - 1的 然后我们求小于等于x的 显然是 \(\sum_{i = 1}^{n} \sum_{j = 1}^{min(i,x)} sum[i] ...

  9. 【LOJ】#2491. 「BJOI2018」求和

    题解 对于50个k都维护一个\(i^k\)前缀和即可 查询的时候就是查询一段连续的区间和,再加上根节点的 代码 #include <bits/stdc++.h> #define fi fi ...

随机推荐

  1. 分布式事务:Saga模式

    1 Saga相关概念 1987年普林斯顿大学的Hector Garcia-Molina和Kenneth Salem发表了一篇Paper Sagas,讲述的是如何处理long lived transac ...

  2. 【JVM】G1垃圾收集器深入分析

    一.和CMS对比   G1 CMS 设计原则 首先收集尽可能多的垃圾(Garbage First) 尽可能少而块地执行GC,以停顿时间为目标 垃圾回收时机  启发式算法,在老年代找出具有高收集收益的分 ...

  3. Spring Cloud的常规组件和简单实战(一)

    最近一段时间在学习Spring Cloud,从Eureka到Hystrix,常用的配置和方法都有涉及一些,以此笔记来记录一下学习到的东西,也分享一下.内容以实战为起点,主要以介绍常规用法为主,最后也会 ...

  4. 小程序mpvue怎么点击按钮获取button里面的值

    在小程序里面是没有dom元素的,这个我们只要会小程序的应该都知道,但是在平时开发中我们偶尔会遇到需要点击某个元素获取它的值的情况,在这里给大家列举了两种情况解决方法 方式一:数据绑定 这种情况的话,对 ...

  5. 面试题:什么叫B树

    B是balanced的意思 是在二叉查找树  树的基础上增加了平衡的性质   导致它不是  二叉树了,变成了多叉树,但是叉几路又有了限制  否则怎么平衡呢 一棵m阶B树(balanced tree o ...

  6. Django知识点归纳总结之HTTP协议与URL

    Django复习知识点归纳总结 1.HTTP协议 ​ 超文本传输协议(Hyper Text Transfer Protocol),是用于万维网服务器与本地浏览器之间的传输超文本的传送协议. ​ HTT ...

  7. springboot 集成百度的唯一ID生成器

    UidGenerator是百度开源的Java语言实现,基于Snowflake算法的唯一ID生成器.而且,它非常适合虚拟环境,比如:Docker.另外,它通过消费未来时间克服了雪花算法的并发限制.Uid ...

  8. MariaDB日志文件、备份与恢复

    1. 数据库的6种日志 数据库有6种日志,分别是:查询日志.慢查询日志.错误日志.二进制日志.中继日志以及事务日志. 1> 查询日志 查询日志记录每一条sql语句,建议不开启,因为如果访问量较大 ...

  9. zabbix--源码安装报错总结

    源码安装 zabbix 报错总结 1)报错: configure: error: MySQL library not found 解决办法 # find / -name "mysql_con ...

  10. kuangbin专题专题四 Til the Cows Come Home POJ - 2387

    题目链接:https://vjudge.net/problem/POJ-2387 题意:从编号为n的城市到编号为1的城市的最短路. 思路:dijkstra模板题,直接套板子,代码中我会带点注释给初学者 ...