【题目链接】
【思路要点】
- 直观地来想,本题可以用矩阵乘法优化递推来实现。
- 但是进制转换并不方便,所以,我们考虑不记录一个方阵的\(2^i\)次方,转而记录一个方阵的\(10^i\)次方,这样就不需要进制转换了。
- 时间复杂度\(O(|N|+|M|)\),由于常数很大,实现时可能需要一定的常数优化。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 1000005; const int P = 1e9 + 7; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 1ll * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int n, m, a, b, c, d; char s[MAXN], t[MAXN]; int matrix[MAXN][3][3]; int natrix[MAXN][3][3]; int tmp[3][3], tnp[3][3]; int now[3][3], res[3][3]; int Now[1][3], Res[1][3]; int main() { scanf("\n%s\n%s", s, t); n = strlen(s); m = strlen(t); reverse(s, s + n); reverse(t, t + m); for (register int i = 0; i < n; i++) if (s[i] == '0') s[i] = '9'; else {s[i]--; break; } for (register int i = 0; i < m; i++) if (t[i] == '0') t[i] = '9'; else {t[i]--; break; } read(a), read(b), read(c), read(d); memset(now, 0, sizeof(now)); matrix[0][1][0] = 1; matrix[0][1][1] = a; matrix[0][2][1] = b; matrix[0][2][2] = 1; now[0][0] = now[1][1] = now[2][2] = 1; for (register int p = 0; p < m; p++) { int cnt = (t[p] - '0') % 5; while (cnt--) { res[0][0] = (1ll * now[0][0] * matrix[p][0][0] + 1ll * now[0][1] * matrix[p][1][0] + 1ll * now[0][2] * matrix[p][2][0]) % P; res[0][1] = (1ll * now[0][0] * matrix[p][0][1] + 1ll * now[0][1] * matrix[p][1][1] + 1ll * now[0][2] * matrix[p][2][1]) % P; res[0][2] = (1ll * now[0][0] * matrix[p][0][2] + 1ll * now[0][1] * matrix[p][1][2] + 1ll * now[0][2] * matrix[p][2][2]) % P; res[1][0] = (1ll * now[1][0] * matrix[p][0][0] + 1ll * now[1][1] * matrix[p][1][0] + 1ll * now[1][2] * matrix[p][2][0]) % P; res[1][1] = (1ll * now[1][0] * matrix[p][0][1] + 1ll * now[1][1] * matrix[p][1][1] + 1ll * now[1][2] * matrix[p][2][1]) % P; res[1][2] = (1ll * now[1][0] * matrix[p][0][2] + 1ll * now[1][1] * matrix[p][1][2] + 1ll * now[1][2] * matrix[p][2][2]) % P; res[2][0] = (1ll * now[2][0] * matrix[p][0][0] + 1ll * now[2][1] * matrix[p][1][0] + 1ll * now[2][2] * matrix[p][2][0]) % P; res[2][1] = (1ll * now[2][0] * matrix[p][0][1] + 1ll * now[2][1] * matrix[p][1][1] + 1ll * now[2][2] * matrix[p][2][1]) % P; res[2][2] = (1ll * now[2][0] * matrix[p][0][2] + 1ll * now[2][1] * matrix[p][1][2] + 1ll * now[2][2] * matrix[p][2][2]) % P; memcpy(now, res, sizeof(res)); } cnt = 4; memcpy(tmp, matrix[p], sizeof(matrix[p])); while (cnt--) { tnp[0][0] = (1ll * tmp[0][0] * matrix[p][0][0] + 1ll * tmp[0][1] * matrix[p][1][0] + 1ll * tmp[0][2] * matrix[p][2][0]) % P; tnp[0][1] = (1ll * tmp[0][0] * matrix[p][0][1] + 1ll * tmp[0][1] * matrix[p][1][1] + 1ll * tmp[0][2] * matrix[p][2][1]) % P; tnp[0][2] = (1ll * tmp[0][0] * matrix[p][0][2] + 1ll * tmp[0][1] * matrix[p][1][2] + 1ll * tmp[0][2] * matrix[p][2][2]) % P; tnp[1][0] = (1ll * tmp[1][0] * matrix[p][0][0] + 1ll * tmp[1][1] * matrix[p][1][0] + 1ll * tmp[1][2] * matrix[p][2][0]) % P; tnp[1][1] = (1ll * tmp[1][0] * matrix[p][0][1] + 1ll * tmp[1][1] * matrix[p][1][1] + 1ll * tmp[1][2] * matrix[p][2][1]) % P; tnp[1][2] = (1ll * tmp[1][0] * matrix[p][0][2] + 1ll * tmp[1][1] * matrix[p][1][2] + 1ll * tmp[1][2] * matrix[p][2][2]) % P; tnp[2][0] = (1ll * tmp[2][0] * matrix[p][0][0] + 1ll * tmp[2][1] * matrix[p][1][0] + 1ll * tmp[2][2] * matrix[p][2][0]) % P; tnp[2][1] = (1ll * tmp[2][0] * matrix[p][0][1] + 1ll * tmp[2][1] * matrix[p][1][1] + 1ll * tmp[2][2] * matrix[p][2][1]) % P; tnp[2][2] = (1ll * tmp[2][0] * matrix[p][0][2] + 1ll * tmp[2][1] * matrix[p][1][2] + 1ll * tmp[2][2] * matrix[p][2][2]) % P; memcpy(tmp, tnp, sizeof(tnp)); } if ((t[p] - '0') / 5) { res[0][0] = (1ll * now[0][0] * tmp[0][0] + 1ll * now[0][1] * tmp[1][0] + 1ll * now[0][2] * tmp[2][0]) % P; res[0][1] = (1ll * now[0][0] * tmp[0][1] + 1ll * now[0][1] * tmp[1][1] + 1ll * now[0][2] * tmp[2][1]) % P; res[0][2] = (1ll * now[0][0] * tmp[0][2] + 1ll * now[0][1] * tmp[1][2] + 1ll * now[0][2] * tmp[2][2]) % P; res[1][0] = (1ll * now[1][0] * tmp[0][0] + 1ll * now[1][1] * tmp[1][0] + 1ll * now[1][2] * tmp[2][0]) % P; res[1][1] = (1ll * now[1][0] * tmp[0][1] + 1ll * now[1][1] * tmp[1][1] + 1ll * now[1][2] * tmp[2][1]) % P; res[1][2] = (1ll * now[1][0] * tmp[0][2] + 1ll * now[1][1] * tmp[1][2] + 1ll * now[1][2] * tmp[2][2]) % P; res[2][0] = (1ll * now[2][0] * tmp[0][0] + 1ll * now[2][1] * tmp[1][0] + 1ll * now[2][2] * tmp[2][0]) % P; res[2][1] = (1ll * now[2][0] * tmp[0][1] + 1ll * now[2][1] * tmp[1][1] + 1ll * now[2][2] * tmp[2][1]) % P; res[2][2] = (1ll * now[2][0] * tmp[0][2] + 1ll * now[2][1] * tmp[1][2] + 1ll * now[2][2] * tmp[2][2]) % P; memcpy(now, res, sizeof(res)); } matrix[p + 1][0][0] = (1ll * tmp[0][0] * tmp[0][0] + 1ll * tmp[0][1] * tmp[1][0] + 1ll * tmp[0][2] * tmp[2][0]) % P; matrix[p + 1][0][1] = (1ll * tmp[0][0] * tmp[0][1] + 1ll * tmp[0][1] * tmp[1][1] + 1ll * tmp[0][2] * tmp[2][1]) % P; matrix[p + 1][0][2] = (1ll * tmp[0][0] * tmp[0][2] + 1ll * tmp[0][1] * tmp[1][2] + 1ll * tmp[0][2] * tmp[2][2]) % P; matrix[p + 1][1][0] = (1ll * tmp[1][0] * tmp[0][0] + 1ll * tmp[1][1] * tmp[1][0] + 1ll * tmp[1][2] * tmp[2][0]) % P; matrix[p + 1][1][1] = (1ll * tmp[1][0] * tmp[0][1] + 1ll * tmp[1][1] * tmp[1][1] + 1ll * tmp[1][2] * tmp[2][1]) % P; matrix[p + 1][1][2] = (1ll * tmp[1][0] * tmp[0][2] + 1ll * tmp[1][1] * tmp[1][2] + 1ll * tmp[1][2] * tmp[2][2]) % P; matrix[p + 1][2][0] = (1ll * tmp[2][0] * tmp[0][0] + 1ll * tmp[2][1] * tmp[1][0] + 1ll * tmp[2][2] * tmp[2][0]) % P; matrix[p + 1][2][1] = (1ll * tmp[2][0] * tmp[0][1] + 1ll * tmp[2][1] * tmp[1][1] + 1ll * tmp[2][2] * tmp[2][1]) % P; matrix[p + 1][2][2] = (1ll * tmp[2][0] * tmp[0][2] + 1ll * tmp[2][1] * tmp[1][2] + 1ll * tmp[2][2] * tmp[2][2]) % P; } memset(tmp, 0, sizeof(tmp)); tmp[1][0] = 1; tmp[1][1] = c; tmp[2][1] = d; tmp[2][2] = 1; for (register int i = 0; i <= 2; i++) for (register int j = 0; j <= 2; j++) for (register int k = 0; k <= 2; k++) natrix[0][i][j] = (natrix[0][i][j] + now[i][k] * 1ll * tmp[k][j]) % P; memset(Now, 0, sizeof(Now)); Now[0][1] = 1, Now[0][2] = 1; for (register int p = 0; p < n; p++) { int cnt = (s[p] - '0') % 5; while (cnt--) { memset(Res, 0, sizeof(Res)); Res[0][0] = (1ll * Now[0][0] * natrix[p][0][0] + 1ll * Now[0][1] * natrix[p][1][0] + 1ll * Now[0][2] * natrix[p][2][0]) % P; Res[0][1] = (1ll * Now[0][0] * natrix[p][0][1] + 1ll * Now[0][1] * natrix[p][1][1] + 1ll * Now[0][2] * natrix[p][2][1]) % P; Res[0][2] = (1ll * Now[0][0] * natrix[p][0][2] + 1ll * Now[0][1] * natrix[p][1][2] + 1ll * Now[0][2] * natrix[p][2][2]) % P; memcpy(Now, Res, sizeof(Res)); } cnt = 4; memcpy(tmp, natrix[p], sizeof(natrix[p])); while (cnt--) { tnp[0][0] = (1ll * tmp[0][0] * natrix[p][0][0] + 1ll * tmp[0][1] * natrix[p][1][0] + 1ll * tmp[0][2] * natrix[p][2][0]) % P; tnp[0][1] = (1ll * tmp[0][0] * natrix[p][0][1] + 1ll * tmp[0][1] * natrix[p][1][1] + 1ll * tmp[0][2] * natrix[p][2][1]) % P; tnp[0][2] = (1ll * tmp[0][0] * natrix[p][0][2] + 1ll * tmp[0][1] * natrix[p][1][2] + 1ll * tmp[0][2] * natrix[p][2][2]) % P; tnp[1][0] = (1ll * tmp[1][0] * natrix[p][0][0] + 1ll * tmp[1][1] * natrix[p][1][0] + 1ll * tmp[1][2] * natrix[p][2][0]) % P; tnp[1][1] = (1ll * tmp[1][0] * natrix[p][0][1] + 1ll * tmp[1][1] * natrix[p][1][1] + 1ll * tmp[1][2] * natrix[p][2][1]) % P; tnp[1][2] = (1ll * tmp[1][0] * natrix[p][0][2] + 1ll * tmp[1][1] * natrix[p][1][2] + 1ll * tmp[1][2] * natrix[p][2][2]) % P; tnp[2][0] = (1ll * tmp[2][0] * natrix[p][0][0] + 1ll * tmp[2][1] * natrix[p][1][0] + 1ll * tmp[2][2] * natrix[p][2][0]) % P; tnp[2][1] = (1ll * tmp[2][0] * natrix[p][0][1] + 1ll * tmp[2][1] * natrix[p][1][1] + 1ll * tmp[2][2] * natrix[p][2][1]) % P; tnp[2][2] = (1ll * tmp[2][0] * natrix[p][0][2] + 1ll * tmp[2][1] * natrix[p][1][2] + 1ll * tmp[2][2] * natrix[p][2][2]) % P; memcpy(tmp, tnp, sizeof(tnp)); } if ((s[p] - '0') / 5) { memset(Res, 0, sizeof(Res)); Res[0][0] = (1ll * Now[0][0] * tmp[0][0] + 1ll * Now[0][1] * tmp[1][0] + 1ll * Now[0][2] * tmp[2][0]) % P; Res[0][1] = (1ll * Now[0][0] * tmp[0][1] + 1ll * Now[0][1] * tmp[1][1] + 1ll * Now[0][2] * tmp[2][1]) % P; Res[0][2] = (1ll * Now[0][0] * tmp[0][2] + 1ll * Now[0][1] * tmp[1][2] + 1ll * Now[0][2] * tmp[2][2]) % P; memcpy(Now, Res, sizeof(Res)); } natrix[p + 1][0][0] = (1ll * tmp[0][0] * tmp[0][0] + 1ll * tmp[0][1] * tmp[1][0] + 1ll * tmp[0][2] * tmp[2][0]) % P; natrix[p + 1][0][1] = (1ll * tmp[0][0] * tmp[0][1] + 1ll * tmp[0][1] * tmp[1][1] + 1ll * tmp[0][2] * tmp[2][1]) % P; natrix[p + 1][0][2] = (1ll * tmp[0][0] * tmp[0][2] + 1ll * tmp[0][1] * tmp[1][2] + 1ll * tmp[0][2] * tmp[2][2]) % P; natrix[p + 1][1][0] = (1ll * tmp[1][0] * tmp[0][0] + 1ll * tmp[1][1] * tmp[1][0] + 1ll * tmp[1][2] * tmp[2][0]) % P; natrix[p + 1][1][1] = (1ll * tmp[1][0] * tmp[0][1] + 1ll * tmp[1][1] * tmp[1][1] + 1ll * tmp[1][2] * tmp[2][1]) % P; natrix[p + 1][1][2] = (1ll * tmp[1][0] * tmp[0][2] + 1ll * tmp[1][1] * tmp[1][2] + 1ll * tmp[1][2] * tmp[2][2]) % P; natrix[p + 1][2][0] = (1ll * tmp[2][0] * tmp[0][0] + 1ll * tmp[2][1] * tmp[1][0] + 1ll * tmp[2][2] * tmp[2][0]) % P; natrix[p + 1][2][1] = (1ll * tmp[2][0] * tmp[0][1] + 1ll * tmp[2][1] * tmp[1][1] + 1ll * tmp[2][2] * tmp[2][1]) % P; natrix[p + 1][2][2] = (1ll * tmp[2][0] * tmp[0][2] + 1ll * tmp[2][1] * tmp[1][2] + 1ll * tmp[2][2] * tmp[2][2]) % P; } memset(Res, 0, sizeof(Res)); for (register int i = 0; i <= 0; i++) for (register int j = 0; j <= 2; j++) for (register int k = 0; k <= 2; k++) Res[i][j] = (Res[i][j] + Now[i][k] * 1ll * now[k][j]) % P; memcpy(Now, Res, sizeof(Res)); writeln(Now[0][1]); return 0; }