2019.8.4中山紀中提高A組題解

鍛造 (forging)

題目描述

在這裏插入圖片描述在這裏插入圖片描述
Input
第一行兩個整數 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;
}

Output

輸出一行一個整數,表示期望花費。

Sample Input

Sample Input1
0 6432
4602677 3944535 2618884 6368297 9477531

Sample Input2
1 3639650
6136976 5520115 2835750 9072363 9302097

Sample Input3
10 2
2 33 6 66 2333333

Sample Input4
200 5708788
0 0 0 0 1

Sample Output

Sample Output1
6432

Sample Output2
150643649

Sample Output3
976750710

Sample Output4
696441597

Data Constraint
在這裏插入圖片描述


題解

不知道爲什麼,看到概率就會想到DpDp
當然這道題顯然是一道DpDp
因爲在考場上我對這道題極其有研究,所以講得稍微詳細一點。
雖然這道題很簡單,但是我們從頭開始(但是我太菜了)。
首先看到n=0n=0,直接就是aa嘛沒什麼可說的。
然後想了一下暫時還有點懵逼(開始讀題讀錯了)。

於是考慮n=1n=1
我們先定義一下(方便表示):f[i]f[i]表示得到一把ii級劍的期望花費
顯然f[0]=af[0]=a
這裏我們想到這個操作可以失敗的次數是不確定的,既是我們假設我們經過i2i-2次失敗後成功,既是需要ii00級劍,然後這種情況對最後答案的貢獻是:
(1p)i2×p×i×f[0](1-p)^{i-2} \times p \times i \times f[0]
可以得到
f[1]=i=2+p×(1p)i2×i×f[0]f[1]=\sum\limits_{i=2}^{+\infty}p\times(1-p)^{i-2}\times i \times f[0]
x=1px=1-p,即
f[1]=p×f[0]×i=2+i×xi2f[1]=p\times f[0]\times\sum\limits_{i=2}^{+\infty}i\times x^{i-2}
所以我們就是要求
i=2+i×xi2\sum\limits_{i=2}^{+\infty}i\times x^{i-2}
S=i=2+i×xi2=2x0+3x1+4x2+......+nxn2S=\sum\limits_{i=2}^{+\infty}i\times x^{i-2}=2x^{0}+3x^{1}+4x^{2}+......+nx^{n-2}
xS=2x1+3x2+4x3+......+(n1)xn2+nxn1xS=2x^{1}+3x^{2}+4x^{3}+......+(n-1)x^{n-2}+nx^{n-1}
(x1)S=nxn1(x1+x2+......+xn2)2(x-1)S=nx^{n-1}-(x^{1}+x^{2}+......+x^{n-2})-2
(x1)S=nxn1xn1xx12(x-1)S=nx^{n-1}-\dfrac{x^{n-1}-x}{x-1}-2
S=nxn(n+1)xn1x+2(x1)2S=\dfrac{nx^{n}-(n+1)x^{n-1}-x+2}{(x-1)^2}
因爲n+,0&lt;x&lt;1n\to +\infty,0&lt;x&lt;1,所以nxn0,(n+1)xn10nx^{n}\to0,(n+1)x^{n-1}\to0
S=2x(x1)2S=\dfrac{2-x}{(x-1)^{2}}
p=1xp=1-x代入SS
S=1+pp2S=\dfrac{1+p}{p^{2}}
所以f[1]=f[0]×1+ppf[1]=f[0]\times \dfrac{1+p}{p}

於是n=1n=1就處理完了,我們再看看還有什麼是容易做的。
看到有p=1p=1再一想,就是除了合成1級劍,其它都是一定成功。
就很容易了。
dp[i]=dp[i1]+dp[i2]dp[i]=dp[i-1]+dp[i-2]
其中dp[0]dp[1]dp[0]和dp[1]知道。

所以我們已經有60分了,NICE
開始考慮正解。
發現每一次合成一把ii級劍,都是要用x{x[1,+]}x \{x\in[1,+\infty]\}i1i-1級劍和1把i2i-2級劍。
類比考慮合成1級劍的過程,我們得到
f[i]=f[i2]+x=1+f[i1]×x×(1p)x1×pf[i]=f[i-2]+\sum_{x=1}^{+\infty} f[i-1]\times x \times (1-p)^{x-1}\times p
大家自己對照前面的過程化簡一下會得到
f[i]=f[i2]+f[i1]pf[i]=f[i-2]+\dfrac{f[i-1]}{p}
這本身也是可以理解的。
再加一個逆元就好了。
要線性篩逆元不然會T。
線性篩逆元


代碼

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=int(1e7+5);
typedef long long LL;
#define mod 998244353
LL n,a;
LL b[MAXN];
LL c[MAXN];
LL dp[MAXN];
LL XINV[MAXN+5];
LL Pow(LL a,LL b) {
    long long ret=1,x=(long long)a,y=(long long)b;
    while(y) {
        if(y%2)
          ret=ret*x%mod;
        y/=2;
        x=(x*x)%mod;
    }
    return LL(ret)%mod;
}
LL Inv(LL a) {
    return Pow(a,mod-2);
}
void Prepare() {
    XINV[1]=1;
    for(int i=2;i<=MAXN;i++)
        XINV[i]=XINV[mod%i]*(mod-mod/i)%mod;
}
int main()
{
    Prepare();
    freopen("forging.in","r",stdin);
    freopen("forging.out","w",stdout);
    LL bx,by,cx,cy,p;
    scanf("%lld%lld",&n,&a);
    scanf("%lld%lld%lld%lld%lld",&bx,&by,&cx,&cy,&p);
    b[0]=by+1,c[0]=cy+1;
    for(LL 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;
    }
    if(n==0) {
        printf("%lld",a);
        return 0;
    }
    else if(p==1||n==1) {
        LL inv=XINV[c[0]],Min=min(c[0],b[0]);
        LL P=(LL)inv*Min%mod;
        LL ans=(LL)a*(1+P)%mod*Inv(P)%mod;
        dp[0]=a,dp[1]=ans;
        for(LL i=2;i<=n;i++)
            dp[i]=(dp[i-1]+dp[i-2])%mod;
        printf("%lld",dp[n]);
    }
    else {
        LL inv=XINV[c[0]],Min=min(c[0],b[0]);
        LL P=(LL)inv*Min%mod;
        LL ans=(LL)a*(1+P)%mod*Inv(P)%mod;
        dp[0]=a,dp[1]=ans;
        for(LL i=2;i<=n;i++) {
            LL MIN=min(c[i-1],b[i-2]);
            LL INV=XINV[MIN];
            dp[i]=((LL)dp[i-1]*c[i-1]%mod*INV%mod+dp[i-2])%mod;
        }
        printf("%lld",dp[n]);
    }
}

如果MLE就把一些LL改爲int


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章