You are viewing a single comment's thread. Return to all comments →
O(logN) solution:
std::vector<std::vector<int>> sq_mul(const std::vector<std::vector<int>> &A, const std::vector<std::vector<int>> &B, long long m) { std::vector<std::vector<int>> C(A.size(), std::vector<int>(B[0].size())); for(int i = 0; i < A.size(); ++i) { for(int j = 0; j < B[0].size(); ++j) { int s = 0; for(int k = 0; k < B.size(); ++k) { s += A[i][k] * B[k][j]; s %= m; } C[i][j] = s; } } return C; } int lin_rec(std::vector<std::vector<int>> M, const std::vector<int>& M0, int N, long long m) { if(N < M0.size()) return M0[N]; N -= M0.size() - 1; std::vector<std::vector<int>> R(M0.size(), std::vector<int>(M0.size())); for(int i = 0; i < M0.size(); ++i) { R[i][i] = 1; } while(N) { if(N & 1) { R = sq_mul(R, M, m); } N >>= 1; M = sq_mul(M, M, m); } int s = 0; for(int j = 0; j < M0.size(); ++j) { s += R[M0.size() - 1][j] * M0[j]; s %= m; } return s; } long long stepPerms(long long n) { // 1, 2, 3 // Fn = Fn-1 + Fn-2 + Fn-3 std::vector<std::vector<int>> M = {{0, 1, 0}, {0, 0, 1}, {1, 1, 1}}; std::vector<int> M0 = {1, 1, 2}; return lin_rec(M, M0, n, 1e10 + 7); }
Seems like cookies are disabled on this browser, please enable them to open this website
Recursion: Davis' Staircase
You are viewing a single comment's thread. Return to all comments →
O(logN) solution: