九校联考-DL24 凉心模拟 Day2T1 锻造 (forging)

勇者寻求锻造高级武器,面对复杂锻造规则与概率,求助智者计算强化至特定等级武器的期望花费。本篇通过解析锻造过程,利用数学序列知识,给出算法实现,帮助勇者高效达成目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

勇者虽然武力值很高,但在经历了多次战斗后,发现怪物越来越难打,于是开始思考是不是自己平时锻炼没到位,于是苦练一个月后发现……自己连一个史莱姆都打不过了。

勇者的精灵路由器告诉勇者其实是他自己的武器不好,并把他指引到了锻造厂。

“欢迎啊,老朋友。”

一阵寒暄过后,厂长带他们参观了厂子四周,并给他们讲锻造的流程。“我们这里的武器分成若干的等级,等级越高武器就越厉害,并且对每一等级的武器都有两种属性值 bbbccc,但是我们初始只能花 aaa 个金币来生产 111000 级剑……”

“所以你们厂子怎么这么垃圾啊,不能一下子就造出来 999999999 级的武器吗?”勇者不耐烦的打断了厂长的话。

“别着急,还没开始讲锻造呢……那我们举例你手中有一把 xxx 级武器和一把 yyy 级武器 (y=max(x−1,0)y = max(x − 1, 0)y=max(x1,0)),我们令锻造附加值 k=min(cx,by)k = min(c_x, b_y)k=min(cx,by),则你有 kcx\frac{k}{c_x}cxk 的概率将两把武器融合成一把 x+1x + 1x+1 级的武器。”

“……但是,锻造不是一帆风顺的,你同样有 1−kcx1-\frac{k}{c_x}1cxk 的概率将两把武器融合成一把 max(x−1,0)max(x − 1, 0)max(x1,0) 级的武器……”

勇者听完后暗暗思忖,他知道厂长一定又想借此机会坑骗他的零花钱,于是求助这个村最聪明的智者——你,来告诉他,想要强化出一把 nnn 级的武器,其期望花费为多少?

由于勇者不精通高精度小数,所以你只需要将答案对 998244353998244353998244353(7×17×223+17 ×17 × 223 + 17×17×223+1,一个质数 ) 取模即可。

输入输出格式

输入格式

第一行两个整数 nnn, aaa,含义如题所示。

为了避免输入量过大,第二行五个整数 bx,by,cx,cy,pbx, by, cx, cy, pbx,by,cx,cy,p,按照下列代码

来生成 bbbccc 数组。

b[0]=by+1;c[0]=cy+1;

for(int i=1;i<=n;++i)
{

	b[i]=((long long)b[i-1]*bx+by)%p+1;

	c[i]=((long long)c[i-1]*cx+cy)%p+1;

}

输出格式

输出一行一个整数,表示期望花费。

输入输出样例

输入样例#1:
10 2
2 33 6 66 2333333
输出样例#1:
976750710

解题分析

首先我们来考虑两把000级的武器合成一把111级的武器期望花费为多少。设成功的概率为ppp000级武器花费为costcostcost,那么显然这个值就为cost+p×cost+p×(1−p)×cost+2×p×(1−p)2×costcost+p\times cost+p\times (1-p)\times cost+2\times p\times (1-p)^2 \times costcost+p×cost+p×(1p)×cost+2×p×(1p)2×cost, 根据数列的知识可以得到这玩意的值是cost+1p×costcost+\frac{1}{p}\times costcost+p1×cost

那么其他情况也就以此类推了。 我们发现合成失败的时候并不会损失x−1x-1x1的, 所以这个概率就只与xxx的期望值有关, 即exp[i]=exp[i−2]+1p×exp[i−1]exp[i]=exp[i-2]+\frac{1}{p}\times exp[i-1]exp[i]=exp[i2]+p1×exp[i1]

代码如下:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <algorithm>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 10000050
#define MOD 998244353
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
#define ll long long
int bx, by, cx, cy, a, n, p, mx;
int b[MX], c[MX], dp[MX], inv[MX];
int main(void)
{
	scanf("%d%d", &n, &a);
	scanf("%d%d%d%d%d", &bx, &by, &cx, &cy, &p);
	b[0] = by + 1; c[0] = cy + 1; mx = max(b[0], c[0]);
	for (R int i = 1; i < n; i++)
	{
		b[i] = (1ll * b[i - 1] * bx + by) % p + 1, mx = max(mx, b[i]);
		c[i] = (1ll * c[i - 1] * cx + cy) % p + 1, mx = max(mx, c[i]);
	}
	inv[1] = 1;
	for (R int i = 2; i <= mx; ++i) inv[i] = 1ll * (MOD - MOD / i) * inv[MOD % i] % MOD;
	dp[0] = a;
	dp[1] = (1ll * inv[min(c[0], b[0])] * dp[0] % MOD * c[0] + dp[0]) % MOD;
	for (R int i = 2; i <= n; ++i) dp[i] = (1ll * inv[min(c[i - 1], b[i - 2])] * dp[i - 1] % MOD * c[i - 1] % MOD + dp[i - 2]) % MOD;
	printf("%d", dp[n]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值