【BZOJ】3240: [Noi2013]矩阵游戏

题意

给出\(n, m(1 \le n, m \le 10^{1000000})\),求\(f(n, m) \ \mod \ 10^9+7\)

$$ \begin{cases} f(1, 1) = 1 \\ f(i, 1) = cf(i-1, m) + d \\ f(i, j) = af(i, j-1) + b & (j \neq 1) \end{cases} $$

其中\(1 \le a, b, c, d \le 10^9\)

分析

对于递推式\(f_i = af_{i-1} + b\)
\(a=1\)时通项为\(f_n = f_1 + (n-1) b\)
\(a \neq 1\)时通项为\(f_n = a^{n-1} f_1 + \frac{b(a^{n-1} - 1)}{a-1}\)
那么根据上式可以求出对应的系数
\[f(i, m) = xf(i, 1) + y\]
然后又得到
\[f(i, 1) = c(xf(i-1, 1) + y)+d = cxf(i-1, 1) + cy + d\]
就可以推出\(f(n, 1)\),最后再逆推回\(f(n, m)\)即可。

题解

快速幂部分,可以根据欧拉定理\(a^{\varphi(p)} \equiv 1 \pmod{p}, (a, p)=1\)可以知道\(a^{10^9+6} \equiv 1 \pmod{10^9+7}\)
所以我们可以在读入的时候就对\(n, m\)\(10^9+6\)然后再快速幂。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mo=1e9+7;
int ipow(int a, int b) {
    if(a>=mo) {
        a%=mo;
    }
    int x=1;
    for(; b; b>>=1, a=(ll)a*a%mo) {
        if(b&1) {
            x=(ll)x*a%mo;
        }
    }
    return x;
}
void getint(int &n, int &nn) {
    char c=getchar();
    n=nn=0;
    for(; c<'0'||c>'9'; c=getchar());
    for(; c>='0'&&c<='9'; c=getchar()) {
        n=((ll)n*10+c-'0')%mo;
        nn=((ll)nn*10+c-'0')%(mo-1);
    }
}
int main() {
    int n, m, nn, mm, a, b, c, d, ans;
    getint(n, nn);
    getint(m, mm);
    scanf("%d%d%d%d", &a, &b, &c, &d);
    int k, j;
    if(a==1) {
        k=c;
        j=((ll)c*(m-1+mo)%mo*b%mo+d)%mo;
    }
    else {
        int p=ipow(a, mm-1+(mo-1));
        k=(ll)c*p%mo;
        j=((ll)b*c%mo*(1-p+mo)%mo*ipow(1-a+mo, mo-2)%mo+d)%mo;
    }
    if(k==1) {
        ans=((ll)n*j%mo+1)%mo;
    }
    else {
        int p=ipow(k, nn);
        ans=((ll)j*ipow(1-k+mo, mo-2)%mo*(1-p+mo)%mo+p)%mo;
    }
    ans=(ans-d+mo)%mo;
    ans=(ll)ans*ipow(c, mo-2)%mo;
    printf("%d\n", ans);
    return 0;
}

转载于:https://www.cnblogs.com/iwtwiioi/p/4985813.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值