Skip to content

Instantly share code, notes, and snippets.

@IvanVergiliev
Created July 12, 2015 12:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IvanVergiliev/3c99b72107cdcab1dfba to your computer and use it in GitHub Desktop.
Save IvanVergiliev/3c99b72107cdcab1dfba to your computer and use it in GitHub Desktop.
Compile time Fibonacci
#include <cstdio>
#include <array>
using std::array;
const int MOD = 1000;
class ArrayWrapper {
const array<int, 2>& value;
public:
constexpr ArrayWrapper(const array<int, 2>& value): value(value) {}
constexpr int operator[](int pos) const {
return value[pos];
}
};
class Matrix {
const array<array<int, 2>, 2> values;
public:
constexpr Matrix(int a, int b, int c, int d): values{{{{a, b}}, {{c, d}}}} {}
constexpr ArrayWrapper operator[](int pos) const {
return values[pos];
}
};
constexpr Matrix ID(1, 0, 0, 1);
constexpr Matrix operator*(const Matrix& a, const Matrix& b) {
int res[2][2] = {{0, 0}, {0, 0}};
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
for (int k = 0; k < 2; ++k) {
(res[i][j] += a[i][k] * b[k][j]) %= MOD;
}
}
}
return Matrix(res[0][0], res[0][1], res[1][0], res[1][1]);
}
constexpr Matrix power(const Matrix& a, long long N) {
if (N == 0) {
return ID;
}
auto half = power(a, N >> 1);
auto res = half * half;
return (N & 1) ? res * a : res;
}
template<long long N>
class Wrapper {
public:
static const auto value = N;
};
constexpr Matrix m(3, 4, 5, 6);
constexpr Matrix fib(1, 1, 1, 0);
constexpr auto r = fib * fib * fib * fib * fib * fib * fib;
constexpr auto p = power(fib, 1LL << 60);
int main() {
printf("%lld\n", Wrapper<p[0][0]>::value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment