Cod sursa(job #3240259)

Utilizator RakoRacovita Dennis Gabriel Rako Data 13 august 2024 15:46:20
Problema Al k-lea termen Fibonacci Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <iostream>
#include <cassert>
#include <vector>

using namespace std;

class Matrix {

  size_t n, m;
  vector<long long> data;

  public:

  long long* operator[](size_t i) { return &data[m * i]; }
  const long long* operator[](size_t i) const { return &data[m * i]; }
  void fill(long long _x) { std::fill(data.begin(), data.end(), _x); }

  friend Matrix operator*(const Matrix& a, const Matrix& b) {
    assert(a.m == b.n);
    Matrix r(a.n, b.m, 0);
    for (int i = 0; i < a.n; i++) {
      for (int k = 0; k < a.m; k++) {
        for (int j = 0; j < b.m; j++) {
          r[i][j] = (a[i][k] * b[k][j] + r[i][j])%666013;
        }
      }
    }
    return r;
  }

  friend Matrix& operator*=(Matrix& a, const Matrix& b) {
    a = a * b;
    return a;
  }

  Matrix(size_t _n, size_t _m, long long _x) : n(_n), m(_m), data(vector<long long>(_n * _m, _x)) {}

  friend void print(const Matrix& a) {
    for (int i = 0; i < a.n; i++) {
      for (int j = 0; j < a.m; j++) {
        cout << a[i][j] << ' ';
      }
      cout << '\n';
    }
  }

  friend Matrix pow(const Matrix& a, long long k) {
    assert(a.n == a.m);
    //luam bitii de la 0 la 62, daca bitul i este 1 inmultim rezultatul cu a la puterea 2^i
    Matrix ans(a.n, a.m, 0);
    for(int i = 0; i < a.n; i++){
      ans[i][i] = 1;
    }
    Matrix b = a;
    for(int i = 0; i < 63; i++){
        if(k&(1LL<<i)){
          ans *= b;
        }
        b*=b; 
    }
    return ans;
  }

};

int main(){
  freopen("kfib.in", "r", stdin);
  freopen("kfib.out", "w", stdout);


  Matrix x(2,2,1);
  x[0][0] = 0;
  long long k;
  cin >> k;
  x = pow(x, k);
  cout << x[0][1];

  return 0;
}