// matrix power in A^p in O(log(p)) vector<vector<int>> matrix_pow(const vector<vector<int>>& A, int p) { if (p == 1) return A; if (p % 2 == 1) return matrix_mul(A, matrix_pow(A, p - 1)); auto B = matrix_pow(A, p / 2); return matrix_mul(B, B); }
int main() { matrix_t m1, m2; std::scanf("%s %s %d %d %d %d", n, m, &a, &b, &c, &d); m1.m[0][0] = a % mod_v, m1.m[0][1] = b % mod_v; m2.m[0][0] = c % mod_v, m2.m[0][1] = d % mod_v; dec(n), dec(m); m1 = matrix_pow(m1, m); m2 = m1 * matrix_pow(m2 * m1, n); std::printf("%lld\n", (m2.m[0][0] + m2.m[0][1]) % mod_v); return 0; }
matrix_t matrix_pow(matrix_t x, const char* p) { matrix_t ans; int len = std::strlen(p); int start = 0; while(p[start] == '0') ++start; for(int i = len - 1; i >= start; --i) { ans = matrix_pow(x, p[i] - '0') * ans; x = matrix_pow(x, 10); } return ans; }
// Matrix Exponentiation - O(log(n)) int matrix_fibo(int n) { if (n == 0) return 0; if (n == 1) return 1; vector<vector<int>> M = { { 1, 1 }, { 1, 0 } }; auto res = matrix_pow(M, n - 1); return res[0][0]; }
int main () { struct Matrix *a = create_matrix(3, 3); struct Matrix *b; read_matrix(a); b = matrix_pow(a, 2); print_matrix(b); return 0; }
/** * Set command */ void command_set(const char* line) { char cmd[MAX_BUFFER]; char key[MAX_BUFFER]; char func[MAX_BUFFER]; char arg1[MAX_BUFFER]; char arg2[MAX_BUFFER]; int argc = sscanf(line, "%s %s = %s %s %s", cmd, key, func, arg1, arg2); if (argc < 3) { puts("invalid arguments"); return; } uint32_t* matrix = NULL; switch (argc) { case 3: if (strcasecmp(func, "identity") == 0) { matrix = identity_matrix(); } else { goto invalid; } break; case 4: if (strcasecmp(func, "random") == 0) { uint32_t seed = atoll(arg1); matrix = random_matrix(seed); } else if (strcasecmp(func, "uniform") == 0) { uint32_t value = atoll(arg1); matrix = uniform_matrix(value); } else if (strcasecmp(func, "cloned") == 0) { MATRIX_GUARD(arg1); matrix = cloned(m); } else if (strcasecmp(func, "reversed") == 0) { MATRIX_GUARD(arg1); matrix = reversed(m); } else if (strcasecmp(func, "transposed") == 0) { MATRIX_GUARD(arg1); matrix = transposed(m); } else { goto invalid; } break; case 5: if (strcasecmp(func, "sequence") == 0) { uint32_t start = atoll(arg1); uint32_t step = atoll(arg2); matrix = sequence_matrix(start, step); } else if (strcasecmp(func, "scalar#add") == 0) { MATRIX_GUARD(arg1); uint32_t value = atoll(arg2); matrix = scalar_add(m, value); } else if (strcasecmp(func, "scalar#mul") == 0) { MATRIX_GUARD(arg1); uint32_t value = atoll(arg2); matrix = scalar_mul(m, value); } else if (strcasecmp(func, "matrix#add") == 0) { MATRIX_GUARD_PAIR(arg1, arg2); matrix = matrix_add(m1, m2); } else if (strcasecmp(func, "matrix#mul") == 0) { MATRIX_GUARD_PAIR(arg1, arg2); matrix = matrix_mul(m1, m2); } else if (strcasecmp(func, "matrix#pow") == 0) { MATRIX_GUARD(arg1); uint32_t exponent = atoll(arg2); matrix = matrix_pow(m, exponent); } else { goto invalid; } break; } entry* e = find_entry(key); if (e == NULL) { e = add_entry(key); } else { free(e->matrix); } e->matrix = matrix; puts("ok"); return; invalid: puts("invalid arguments"); }