天依题!|| solution - P6395
天依题!
这边支持一下绫功依受呢喵~
天依是真的可爱呀 ww
先形式化一下题意:
令当前吃过的店铺数为「血量」。
定义一次操作为依次执行以下操作:
- 重复当前血量次,以
p = \frac a b 的概率血量减少1 ,并且血量的下限为0 。- 以
\frac {\text 当前血量} n 的概率血量增加1 。求血量达到
n 的期望操作次数。
没错,你会发现,这样好端端的一个天依题就变成了治疗之雨。
为什么要把增加放在后面呢?因为题意要求,判定是在吃完一个店铺之后立即进行的,并不包括这个时刻和下一个时刻之间的撤场事件。所以这样定义方便一点。
dp,令
先递推
注意到有环没法直接递推,
关于
时间复杂度还是
代码为了方便,直接把
最后要输出
int n;
mint p,a[N][N],f[N];
il void gauss(int n)
{
reverse(a+1,a+n+1); rep(i,1,n) reverse(a[i]+1,a[i]+n+1);
int r=1,mx; mint t;
rep(j,1,n)
{
mx=r; rep(i,r,r+1) if(a[i][j]>0) {mx=i; break;}
mx^r && (swap(a[mx],a[r]),1);
t=a[r+1][j]/a[r][j];
rep(k,r,n+1) a[r+1][k]-=t*a[r][k];
++r;
}
rpe(j,n,1)
{
f[n-j+1]=a[j][n+1]/a[j][j];
rep(i,1,j-1) a[i][n+1]-=a[i][j]*f[j],a[i][j]=0;
}
}
il void solve()
{
read(n); {int x,y; read(x,y),p=x*ginv(y);}
if(n==1) return write(1ll);
mint iv=ginv(n);
rep(i,1,n-1)
{
a[i][i]=-1.,a[i][n]=-1.;
rep(j,0,i)
{
i-j+1^n && (a[i][i-j+1]+=C(i,j)*fpow(p,j)*fpow(1-p,i-j)*(n-(i-j))*iv,1);
a[i][i-j]+=C(i,j)*fpow(p,j)*fpow(1-p,i-j)*(i-j)*iv;
}
}
gauss(n-1);
write((int)f[1]+1);
}
华风夏韵,洛水天依!
Tip:并不仅仅是天依题的题解里才有最后这句话哦!