题面

传送门(loj)

传送门(洛谷)

题解

模拟赛的时候只想出了高斯消元然后死活不知道怎么继续……结果正解居然就是高斯消元卡常?

首先有个比较难受的地方是它一个回合可能不止扣一滴血……我们得算出\(P_i\)表示一回合扣\(i\)滴血的概率,为

\[P_i={{k\choose i}m^{k-i}\over (m+1)^k}
\]

所以这个柿子啥意思?

我们可以把\(k\)次扣血看成一个长度为\(k\)的序列,每个序列有\(m+1\)种选择方法,于是总的选法就是\((m+1)^k\)。我们要钦定它扣\(i\)滴血,就是令其中\(i\)个数强制选择\(1\),方案数为\({k\choose i}\)。剩下的数都不能选\(1\),所以方案数为\(m^{k-i}\)

有了这个\(P_i\)我们就可以考虑找关系了

然而这里还有一个很讨厌的地方就是它时不时会被奶一口……

我们记\(f_i\)表示当血量为\(i\)时被干掉的期望回合数,\(g_i\)表示一回合内打出伤害大于等于\(i\)的概率,然后考虑这东西该怎么转移

\[f_i={m\over m+1}\left(g_i+\sum_{k=0}^{i-1}P_k(f_{i-k}+1)\right)+{1\over m+1}\left(g_{i+1}+\sum_{k=0}^{i}P_k(f_{i+1-k}+1)\right)
\]

边界条件为

\[f_n=g_n+\sum_{k=0}^{n-1}P_k(f_{n-k}+1)
\]

所以这柿子是啥?

\({m\over m+1}\)表示没有被奶到的概率,那么我们枚举它被\(A\)了几下。如果它一回合被干掉了,那么期望局数为\(1\),否则\(A\)了\(k\)下之后血量会到\(i-k\),这一部分的期望步数就是\(f_{i-k}+1\)。后面那个就是如果被奶了之后的情况。顺便因为满血的时候是不可能被奶的,所以\(f_n\)要特殊考虑

然而这柿子一点都不好看,特别是\(g_i\)很不爽,那就继续推倒

\[f_i={m\over m+1}\left(g_i+\sum_{k=0}^{i-1}P_k+\sum_{k=0}^{i-1}P_kf_{i-k}\right)+{1\over m+1}\left(g_{i+1}+\sum_{k=0}^{i}P_k+\sum_{k=0}^{i}P_kf_{i+1-k}\right)
\]

\[f_i={m\over m+1}\left(1+\sum_{k=0}^{i-1}P_kf_{i-k}\right)+{1\over m+1}\left(1+\sum_{k=0}^{i}P_kf_{i+1-k}\right)
\]

同理有\(f_n=1+\sum_{k=0}^{n-1}P_kf_{n-k}\)

那么我们就可以愉快地递推……等会儿这咋推啊……转移好像都成环了啊……

那么我们就把它看成一个方程组来高斯消元求解吧

哈?\(n=1500\)你让我高斯消元?

我们来好好观察一下这个方程组,\(f_i\)所对应的方程只与\(f_1,...f_{i+1}\)的值有关,也就是说每一行的对角线右边只有在它右边一位的那个系数不为\(0\)

因为我们高斯消元的时候是拿自己这行去减下面的,所以每一行中只有\(2\)个系数要去和下面的相减,复杂度就能化到\(O(n^2)\)了

虽然我还是不知道这个复杂度是怎么过去的

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int K=-1,Z=0;
inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
void print(R int x){
if(K>1<<20)Ot();if(x<0)sr[++K]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++K]=z[Z],--Z);sr[++K]='\n';
}
const int N=1505,P=1e9+7;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
int a[N][N],ans[N],s[N],inv[N],g[N];
int n,m,p,k,T,qwq,aa,bb,tmp,res;
void init(int n){
inv[0]=inv[1]=1;
fp(i,2,n)inv[i]=mul(P-P/i,inv[P%i]);
}
void Gauss(int n){
fp(i,1,n-1){
int t=ksm(a[i][i],P-2);
a[i][i]=1,a[i][n]=mul(a[i][n],t);
if(i!=n-1)a[i][i+1]=mul(a[i][i+1],t);
fp(j,i+1,n-1){
t=a[j][i],a[j][i]=0;
a[j][i+1]=dec(a[j][i+1],mul(t,a[i][i+1])),
a[j][n]=dec(a[j][n],mul(t,a[i][n]));
}
}
ans[n-1]=a[n-1][n];
fd(i,n-2,1)ans[i]=dec(a[i][n],mul(a[i][i+1],ans[i+1]));
}
int main(){
// freopen("testdata.in","r",stdin);
T=read();
init(N-5);
while(T--){
n=read(),p=read(),m=read(),k=read();
if(!k||(!m&&k==1)){puts("-1");continue;}
if(!m){
while(p>0){if(p<n)++p;p-=k,++res;}
printf("%d\n",res),res=0;continue;
}
qwq=ksm(m+1,k),qwq=ksm(qwq,P-2)%P,tmp=1;
fp(i,0,n)s[i]=0;
fp(i,0,min(n,k)){
s[i]=1ll*tmp*ksm(m,k-i)%P*qwq%P;
tmp=1ll*tmp*inv[i+1]%P*(k-i)%P;
}
memset(a,0,sizeof(a));
bb=ksm(m+1,P-2),aa=mul(m,bb);
fp(i,1,n-1){
++a[i][i],++a[i][n+1];
fp(j,0,i-1)a[i][i-j]=dec(a[i][i-j],mul(s[j],aa));
fp(j,0,i)a[i][i+1-j]=dec(a[i][i+1-j],mul(s[j],bb));
}
++a[n][n],++a[n][n+1];
fp(j,0,n-1)a[n][n-j]=dec(a[n][n-j],s[j]);
Gauss(n+1);
printf("%d\n",ans[p]);
}
return 0;
}

洛谷P4457/loj#2513 [BJOI2018]治疗之雨(高斯消元+概率期望)的更多相关文章

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

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

  2. 洛谷P4035 [JSOI2008]球形空间产生器(高斯消元)

    洛谷题目传送门 球啊球 @xzz_233 qaq 高斯消元模板题,关键在于将已知条件转化为方程组. 可以发现题目要求的未知量有\(n\)个,题目却给了我们\(n+1\)个点的坐标,这其中必有玄机. 由 ...

  3. 【洛谷U20626】gemo 容斥 FWT 高斯消元

    题目大意 给你一个无向图,有\(m\)个询问,每次给你一个点\(x\)和一个点集\(S\),问你从\(x\)开始走,每次从一个点随机的走到与这个点相邻的点,问你访问\(S\)中每个点至少一次的期望步数 ...

  4. LOJ 2542 「PKUWC2018」随机游走 ——树上高斯消元(期望DP)+最值反演+fmt

    题目:https://loj.ac/problem/2542 可以最值反演.注意 min 不是独立地算从根走到每个点的最小值,在点集里取 min ,而是整体来看,“从根开始走到点集中的任意一个点就停下 ...

  5. BZOJ5291/洛谷P4458/LOJ#2512 [Bjoi2018]链上二次求和 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/9031130.html 题目传送门 - LOJ#2512 题目传送门 - 洛谷P4458 题目传送门 - BZOJ ...

  6. 洛谷P4459/loj#2511 [BJOI2018]双人猜数游戏(博弈论)

    题面 传送门(loj) 传送门(洛谷) 题解 所以博弈论的本质就是爆搜么-- 题解 //minamoto #include<bits/stdc++.h> #define R registe ...

  7. 洛谷P4458 /loj#2512.[BJOI2018]链上二次求和(线段树)

    题面 传送门(loj) 传送门(洛谷) 题解 我果然是人傻常数大的典型啊-- 题解在这儿 //minamoto #include<bits/stdc++.h> #define R regi ...

  8. 洛谷P3343 [ZJOI2015]地震后的幻想乡 [DP,概率期望]

    传送门 思路 题目给了一个提示:对于\(n\)个\([0,1]\)的随机变量,其中第\(k\)小的期望大小是\(\frac{k}{n+1}\). 这引导我们枚举边的相对大小的全排列,然后求最小生成树 ...

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

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

随机推荐

  1. $route路由

    <!DOCTYPE html><html ng-app="AngularApp"> <head> <meta charset=" ...

  2. mycat 实践扩容

    实践扩容, travelrecord表定义为10个分片,尝试将10个分片中的2个分片转移到第二台MySQL上 1--定义10个分片<table name="travelrecord_t ...

  3. c# 设置水印,消除水印

    方案1: 图像处理 opencv etc 方案2: 开源框架,直接使用,已经优化 https://github.com/itext/itextsharp https://github.com/itex ...

  4. 侯捷STL学习(九)--关联式容器(Rb_tree,set,map)

    layout: post title: 侯捷STL学习(九) date: 2017-07-21 tag: 侯捷STL --- 第十九节 容器rb_tree Red-Black tree是自平衡二叉搜索 ...

  5. python IOError: windows directory not found at xxxxx win32

    您需要修改 PATH 环境变量,将Python的可执行程序及额外的脚本添加到系统路径中.将以下路径添加到 PATH 中: C:\Python2.7\;C:\Python2.7\Scripts\;请打开 ...

  6. ks8基础(1) etcd安装

    下载安装 https://github.com/coreos/etcd/releases 在这网页,可以看到有多个版本共选择. 下载3.25 解压后, cd etcd-v3.2.5-linux-amd ...

  7. oracle中函数和存储过程的区别和联系

    oracle中函数和存储过程的区别和联系 在oracle中,函数和存储过程是经常使用到的,他们的语法中有很多相似的地方,但也有自己的特点.刚学完函数和存储过程,下面来和大家分享一下自己总结的关于函数和 ...

  8. SQLiteopenhelper创建database的过程

    首先由于SQLiteOpenHelper是一个抽象类,所以我们要创建一个自己的类实现它,并实现抽象方法, public void onCreate(SQLiteDatabase db) public ...

  9. CentOS 7 下设置DNS

    在CentOS 7下,手工设置 /etc/resolv.conf 里的DNS,过了一会,发现被系统重新覆盖或者清除了.和CentOS 6下的设置DNS方法不同,有几种方式: 1.使用全新的命令行工具 ...

  10. java 矩阵转置算法

    工作中用到了行列转置,把这两种情况的算法记下来,以便后用 1.行列数相等的转置 /** * @description 矩阵转置 * @author oldmonk * @time 2017年8月18日 ...