“欢迎啊,老朋友。”
一阵寒暄过后,厂长带他们参观了厂子四周,并给他们讲锻造的流程。
“我们这里的武器分成若干的等级,等级越高武器就越厉害,并且对每
一等级的武器都有两种属性值 b 和 c,但是我们初始只能花 a 个金币来生
产 1 把 0 级剑……”
“所以你们厂子怎么这么垃圾啊,不能一下子就造出来 999 级的武器
吗?”勇者不耐烦的打断了厂长的话。
“别着急,还没开始讲锻造呢……那我们举例你手中有一把 x 级武器和
一把
y
y
y 级武器
(
y
=
m
a
x
(
x
−
1
,
0
)
)
(y = max(x − 1, 0))
(y=max(x−1,0)),我们令锻造附加值
k
=
m
i
n
(
c
x
,
b
y
)
k = min(cx, by)
k=min(cx,by),则
你有
k
c
x
\frac{k}{cx}
cxk 的概率将两把武器融合成一把 x + 1 级的武器。”
“……但是,锻造不是一帆风顺的,你同样有
1
−
k
c
x
\frac{1 −k}{cx}
cx1−k 的概率将两把武器
融合成一把
m
a
x
(
x
−
1
,
0
)
max(x − 1, 0)
max(x−1,0) 级的武器……”
勇者听完后暗暗思忖,他知道厂长一定又想借此机会坑骗他的零花钱,
于是求助这个村最聪明的智者——你,来告诉他,想要强化出一把 n 级的
武器,其期望花费为多少?
由于勇者不精通高精度小数,所以你只需要将答案对
998244353
(
7
×
17
×
2
23
+
1
,
一
个
质
数
)
998244353(7 × 17 × 2 ^{23} + 1,一个质数 )
998244353(7×17×223+1,一个质数) 取模即可。
非常模板的期望DP:
定义:
F
i
F_{i}
Fi为强化到
i
i
i级的期望费用
我们考虑
F
i
F_{i}
Fi从
F
i
−
1
F_{i-1}
Fi−1转移过来
在
i
i
i不为1的时候:
有
P
i
P_{i}
Pi的概率成功,这个实际上就是:
F
i
=
(
F
i
−
1
+
F
i
−
2
)
∗
P
i
F_{i}=(F_{i-1}+F_{i-2})*P_{i}
Fi=(Fi−1+Fi−2)∗Pi
但是有可能失败这个时候获得了一个
F
i
−
2
F_{i-2}
Fi−2
那么再花费一个
F
i
−
1
F_{i-1}
Fi−1就可以开始合成即综上
F
i
=
(
F
i
−
2
+
F
i
−
1
)
∗
P
i
+
(
F
i
+
F
i
−
1
)
∗
(
1
−
P
i
)
F_{i}=(F_{i-2}+F_{i-1})*P_{i}+(F_{i}+F{i-1})*(1-P_{i})
Fi=(Fi−2+Fi−1)∗Pi+(Fi+Fi−1)∗(1−Pi)
解析一下就好了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int N=1e7+10;
typedef long long LL;
const LL mod=998244353;
LL F[N];
int Inv[N];
int B[N];
int C[N];
LL bx,by,cx,cy,a;
int n;
LL p;
void Pre(){
B[0]=by+1;C[0]=cy+1;
for(int i=1;i<n;++i){
B[i]=((LL)B[i-1]*bx+by)%p+1;
C[i]=((LL)C[i-1]*cx+cy)%p+1;
}
Inv[1]=1;
for(int i=2;i<=1e7;++i){
Inv[i]=1LL*(mod-mod/i)*Inv[mod%i]%mod;
}
}
signed main(){
freopen("forging.in","r",stdin);
freopen("forging.out","w",stdout);
cin>>n>>a>>bx>>by>>cx>>cy>>p;
Pre();
F[0]=a;
F[1]=a*(1LL+1LL*C[0]*Inv[min(B[0],C[0])]%mod)%mod;
for(int i=2;i<=n;++i){
F[i]=(F[i-2]+1LL*C[i-1]*F[i-1]%mod*Inv[min(B[i-2],C[i-1])]%mod)%mod;
}
cout<<F[n]<<'\n';
return 0;
}