锻造(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$ |
解析
还记得马尔可夫的方程吗?
求一个硬币抛到正面的期望,等于他上一次抛的期望,如果这一次没抛到正面,抛的次数加一,继续抛,如果抛到正面就停止。其中系数\(\frac{1}{2}\)是概率k。
同样的,我们也可以用这个方法求期望。
\(f[i]\)表示一个武器的期望花费
仿照马尔可夫理论,整理成那个方程的形式,递推算就好了。
代码
#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) 编辑 收藏 举报