:) Ch_someone

Ch_someone

锻造(forging)

——九校联考24OI__D1T1

题目背景

    勇者虽然武力值很高,但在经历了多次战斗后,发现怪物越来越难打,于是开始思考是不是自己平时锻炼没到位,于是苦练一个月后发现……自己连一个史莱姆都打不过了。
    勇者的精灵路由器告诉勇者其实是他自己的武器不好,并把他指引到了锻造厂。

题目描述

“欢迎啊,老朋友。”
一阵寒暄过后,厂长带他们参观了厂子四周,并给他们讲锻造的流程。
“我们这里的武器分成若干的等级,等级越高武器就越厉害,并且对每一等级的武器都有两种属性值\(b\)\(c\),但是我们初始只能花\(a\) 个金币来生产\(1\)\(0\) 级剑……”
“所以你们厂子怎么这么垃圾啊,不能一下子就造出来 \(999\) 级的武器吗?”勇者不耐烦的打断了厂长的话。
“别着急,还没开始讲锻造呢……那我们举例你手中有一把\(x\)级武器和一把\(y\)级武器\(y=max(x_1,0)\) ,我们令锻造附加值 \(k = min(c_x,b_y)\),则你有kcx的概率将两把武器融合成一把\(x + 1\)级的武器。”
“……但是,锻造不是一帆风顺的,你同样有1 􀀀 kcx的概率将两把武器融合成一把max(x 􀀀 1; 0) 级的武器……”
勇者听完后暗暗思忖,他知道厂长一定又想借此机会坑骗他的零花钱,于是求助这个村最聪明的智者——你,来告诉他,想要强化出一把n 级的武器,其期望花费为多少?
由于勇者不精通高精度小数,所以你只需要将答案对\(998244353\)(\(7 \times 17 \times 2^{23} + 1\),一个质数) 取模即可。

格式

输入格式

第一行两个整数n; a,含义如题所示。
为了避免输入量过大,第二行五个整数bx; by; cx; cy; p,按照下列代码
来生成b 和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 输入

    0 6432
    4602677 3944535 2618884 6368297 9477531

样例1 输出

    6432

样例2 输入

    1 3639650
    6136976 5520115 2835750 9072363 9302097

样例2 输出

    150643649

样例3 输入

    10 2
    2 33 6 66 2333333

样例3 输出

    976750710
    3

样例4 输入

    200 5708788
    0 0 0 0 1

样例4 输出

    696441597

数据范围

测试点 n<= 特殊性质
1 0 N/A
2 1 N/A
3 200
4 200 N/A
5 2000
6 2000 N/A
7 1000000
8 1000000 N/A
9 10000000
10 10000000 N/A
对于特殊性质处标示为“有”的数据满足\(p = 1\)
对于$100 % $的数据,\(0 <=a <=10^7\); \(0 < bx,by, cx, cy < p < 10^7\); $0 < n <
10^7$

解析

还记得马尔可夫的方程吗?

\[x = \frac{x}{2} + 1 \]

求一个硬币抛到正面的期望,等于他上一次抛的期望,如果这一次没抛到正面,抛的次数加一,继续抛,如果抛到正面就停止。其中系数\(\frac{1}{2}\)是概率k。
同样的,我们也可以用这个方法求期望。
\(f[i]\)表示一个武器的期望花费

\[f[i] = f[i-1] + f[i-2] + (1 - \frac{b[i-2]}{c[i-1]}) \times (f[i] - f[i-2]) \]

仿照马尔可夫理论,整理成那个方程的形式,递推算就好了。

代码

#include<cmath>
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
typedef long long ll;
const int p=998244353;
const int N=1e7+5;
inline int read()
{
	int X=0,w=0;
	char ch=0;
	while(!isdigit(ch))
	{
		w|=ch=='-';
		ch=getchar();
	}
	while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
	return w?-X:X;
}
int inv[N],b[N],c[N],f[N];
inline int sub(int x,int y)
{
	x-=y;
	if(x<0)x+=p;
	return x;
}
int main()
{
//	freopen("forging.in","r",stdin);
//	freopen("forging.out","w",stdout);
	inv[1]=1;
	for(int i=2; i<N; i++)inv[i]=(ll)(p-p/i)*inv[p%i]%p;

	int n=read();
	f[0]=read();
	int bx=read(),by=read(),cx=read(),cy=read(),mod=read();
	b[0]=by+1;
	c[0]=cy+1;
	for(int i=1; i<n; i++)
	{
		b[i]=((ll)b[i-1]*bx+by)%mod+1;
		c[i]=((ll)c[i-1]*cx+cy)%mod+1;
	}
	f[1]=(ll)((ll)c[0]*inv[min(b[0],c[0])]%p+1)*f[0]%p;
	for(int i=2; i<=n; i++)
		f[i]=((ll)c[i-1]*inv[min(b[i-2],c[i-1])]%p*f[i-1]%p+f[i-2])%p;
	printf("%d\n",f[n]);
	return 0;
}

posted on 2018-09-17 18:31  Ch_someone  阅读(568)  评论(0编辑  收藏  举报

导航