1. 程式人生 > >九校聯考-DL24 涼心模擬 Day2T1 鍛造 (forging)

九校聯考-DL24 涼心模擬 Day2T1 鍛造 (forging)

題目描述

勇者雖然武力值很高,但在經歷了多次戰鬥後,發現怪物越來越難打,於是開始思考是不是自己平時鍛鍊沒到位,於是苦練一個月後發現……自己連一個史萊姆都打不過了。

勇者的精靈路由器告訴勇者其實是他自己的武器不好,並把他指引到了鍛造廠。

“歡迎啊,老朋友。”

一陣寒暄過後,廠長帶他們參觀了廠子四周,並給他們講鍛造的流程。“我們這裡的武器分成若干的等級,等級越高武器就越厲害,並且對每一等級的武器都有兩種屬性值 bbcc,但是我們初始只能花 aa 個金幣來生產 1100 級劍……”

“所以你們廠子怎麼這麼垃圾啊,不能一下子就造出來 999999 級的武器嗎?”勇者不耐煩的打斷了廠長的話。

“彆著急,還沒開始講鍛造呢……那我們舉例你手中有一把 xx 級武器和一把 yy 級武器 (y=max(x1,0)y = max(x − 1, 0)),我們令鍛造附加值 k=min(cx,by)k = min(c_x, b_y),則你有 kcx\frac{k}{c_x} 的概率將兩把武器融合成一把 x+1x + 1 級的武器。”

“……但是,鍛造不是一帆風順的,你同樣有 1kcx1-\frac{k}{c_x} 的概率將兩把武器融合成一把 max(x1,0)max(x − 1, 0) 級的武器……”

勇者聽完後暗暗思忖,他知道廠長一定又想借此機會坑騙他的零花錢,於是求助這個村最聰明的智者——你,來告訴他,想要強化出一把 nn 級的武器,其期望花費為多少?

由於勇者不精通高精度小數,所以你只需要將答案對 998244353998244353(7×17×223+17 ×17 × 223 + 1,一個質數 ) 取模即可。

輸入輸出格式

輸入格式

第一行兩個整數 nn, aa,含義如題所示。

為了避免輸入量過大,第二行五個整數 bx,by,cx,cy,pbx, by, cx, cy, p,按照下列程式碼

來生成 bbc

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

解題分析

首先我們來考慮兩把00級的武器合成一把11級的武器期望花費為多少。設成功的概率為pp00級武器花費為costcost,那麼顯然這個值就為cost+p×cost+p×(1p)×cost+2×p×(1p)2×costcost+p\times cost+p\times (1-p)\times cost+2\times p\times (1-p)^2 \times cost, 根據數列的知識可以得到這玩意的值是cost+1p×costcost+\frac{1}{p}\times cost

那麼其他情況也就以此類推了。 我們發現合成失敗的時候並不會損失x1x-1的, 所以這個概率就只與xx的期望值有關, 即exp[i]=exp[i2]+1p×exp[i1]exp[i]=exp[i-2]+\frac{1}{p}\times exp[i-1]

程式碼如下:

#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]);
}