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

题目描述

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

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

“欢迎啊,老朋友。”

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

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

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

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

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

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

输入输出格式

输入格式

第一行两个整数 n n n, a a a,含义如题所示。

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

来生成 b b b c c c 数组。

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

解题分析

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

那么其他情况也就以此类推了。 我们发现合成失败的时候并不会损失 x − 1 x-1 x1的, 所以这个概率就只与 x x x的期望值有关, 即 e x p [ i ] = e x p [ i − 2 ] + 1 p × e x p [ 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]);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值