题目转化为
$f(n) = m * f(n - 1) + a$
$f(n + 1) = m * f(n) + a$
两式相减得
$f(n + 1) = (m + 1) * f(n) - m * f(n - 1)$
求$f(n)$
其中$m$为$10^{k}$ ($k$为$a$的位数)
那么利用矩阵快速幂加速就可以了。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) typedef long long LL; struct Matrix{ LL arr[5][5];} init, unit, Unit; int T; LL a, n, mod; inline LL Pow(LL a, LL b, LL Mod){ LL ret(1); for (; b; b >>= 1, (a *= a) %= Mod) if (b & 1) (ret *= a) %= Mod; return ret; } Matrix Mul(Matrix a, Matrix b){ Matrix c; rep(i, 1, 2) rep(j, 1, 2){ c.arr[i][j] = 0; rep(k, 1, 2) (c.arr[i][j] += (a.arr[i][k] * b.arr[k][j] % mod)) %= mod; } return c; } Matrix MatrixPow(Matrix a, LL k){ Matrix ret(Unit); for (; k; k >>= 1, a = Mul(a, a)) if (k & 1) ret = Mul(ret, a); return ret; } inline LL calc(LL n){ LL ret(0); for (; n; n /= 10) ++ret; return ret; } int main(){ scanf("%d", &T); while (T--){ Unit.arr[1][1] = Unit.arr[2][2] = 1; scanf("%lld%lld%lld", &a, &n, &mod); if (a == 0LL){ puts("0"); continue; } LL exp = calc(a), m = Pow(10, exp, mod); LL f1 = a % mod, f2 = ((f1 * m) % mod + a) % mod; LL f3 = ((f2 * m) % mod + a) % mod; if (n == 1LL){ printf("%lld ", f1 % mod); continue; } if (n == 2LL){ printf("%lld ", f2 % mod); continue; } if (n == 3LL){ printf("%lld ", f3 % mod); continue; } LL num = (2 * mod - m) % mod; init.arr[1][1] = f3, init.arr[1][2] = init.arr[2][1] = f2, init.arr[2][2] = f1; unit.arr[1][1] = m + 1, unit.arr[1][2] = num, unit.arr[2][1] = 1, unit.arr[2][2] = 0; Matrix mul = MatrixPow(unit, n - 3); Matrix ret = Mul(mul, init); printf("%lld ", ret.arr[1][1]); } return 0; }