Cod sursa(job #2219244)

Utilizator IulianOleniucIulian Oleniuc IulianOleniuc Data 7 iulie 2018 23:22:45
Problema Al k-lea termen Fibonacci Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.22 kb
#include <fstream>
#define MOD 666013

std::ifstream fin("kfib.in");
std::ofstream fout("kfib.out");

// struct ce reține o matrice 2x2
struct Mat {
    long long int mat[2][2];
};

// elementul neutru la înmulțirea matricelor 2x2
const Mat nullMat = {
    {{1, 0},
     {0, 1}}
};

// matricea pe care o ridicăm la puterea k
const Mat initMat = {
    {{1, 1},
     {1, 0}}
};

int k;

/// Funcție ce calculează a * b
Mat prod(Mat a, Mat b) {
    Mat ret;
    ret.mat[0][0] = (a.mat[0][0] * b.mat[0][0] % MOD + a.mat[0][1] * b.mat[1][0] % MOD) % MOD;
    ret.mat[0][1] = (a.mat[0][0] * b.mat[0][1] % MOD + a.mat[0][1] * b.mat[1][1] % MOD) % MOD;
    ret.mat[1][0] = (a.mat[1][0] * b.mat[0][0] % MOD + a.mat[1][1] * b.mat[1][0] % MOD) % MOD;
    ret.mat[1][1] = (a.mat[1][0] * b.mat[0][1] % MOD + a.mat[1][1] * b.mat[1][1] % MOD) % MOD;
    return ret;
}

/// Funcție recursivă pentru calcularea mat^n
Mat pow(Mat mat, int n) {
    if (!n)
        return nullMat;

    if (n & 1)
        return prod(mat, pow(prod(mat, mat), n >> 1));
    return pow(prod(mat, mat), n >> 1);
}

int main() {
    fin >> k;
    fout << pow(initMat, k).mat[0][1] << '\n';

    fout.close();
    return 0;
}