【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(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)aa%mo) {
if(b&1) {
x=(ll)xa%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)n10+c-'0')%mo;
nn=((ll)nn10+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(a1) {
k=c;
j=((ll)c(m-1+mo)%mob%mo+d)%mo;
}
else {
int p=ipow(a, mm-1+(mo-1));
k=(ll)cp%mo;
j=((ll)bc%mo(1-p+mo)%moipow(1-a+mo, mo-2)%mo+d)%mo;
}
if(k1) {
ans=((ll)nj%mo+1)%mo;
}
else {
int p=ipow(k, nn);
ans=((ll)jipow(1-k+mo, mo-2)%mo(1-p+mo)%mo+p)%mo;
}
ans=(ans-d+mo)%mo;
ans=(ll)ansipow(c, mo-2)%mo;
printf("%d\n", ans);
return 0;
}

浙公网安备 33010602011771号