Cod sursa(job #3124222)

Utilizator vladorovOroviceanu Vlad vladorov Data 27 aprilie 2023 11:48:44
Problema Al k-lea termen Fibonacci Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.26 kb
#include <iostream>
#include <fstream>

using namespace std;

typedef long long i64;

class Vector_2{
private:
    i64 vector_x;
    i64 vector_y;

public:
    i64& x(){
        return vector_x;
    }

    const i64& x() const{
        return vector_x;
    }

    i64& y(){
        return vector_y;
    }

    const i64& y() const{
        return vector_y;
    }

    Vector_2(i64 new_x, i64 new_y){
        this->x()=new_x;
        this->y()=new_y;
    }

    Vector_2(const Vector_2& new_vector){
        this->x()=new_vector.x();
        this->y()=new_vector.y();
    }

};

class Matrix_2{
private:
    i64 Matrix_11;
    i64 Matrix_12;
    i64 Matrix_21;
    i64 Matrix_22;

public:
    i64& at(i64 row, i64 col){
        if(row==1 && col==1) return Matrix_11;
        if(row==1 && col==2) return Matrix_12;
        if(row==2 && col==1) return Matrix_21;
        if(row==2 && col==2) return Matrix_22;
    }

    const i64& at(i64 row, i64 col) const{
        if(row==1 && col==1) return Matrix_11;
        if(row==1 && col==2) return Matrix_12;
        if(row==2 && col==1) return Matrix_21;
        if(row==2 && col==2) return Matrix_22;
    }

    Matrix_2(i64 new_11, i64 new_12, i64 new_21, i64 new_22){
        this->at(1, 1)=new_11;
        this->at(1, 2)=new_12;
        this->at(2, 1)=new_21;
        this->at(2, 2)=new_22;
    }

    Matrix_2(const Matrix_2& new_matrix){
        for(int i=1; i<=2; i++){
            for(int j=1; j<=2; j++){
                this->at(i, j)=new_matrix.at(i, j);
            }
        }
    }

};

#define I Matrix_2(1, 0, 0, 1)

Matrix_2 operator*(const Matrix_2& matrix1, const Matrix_2& matrix2){
    int new_11=matrix1.at(1, 1)*matrix2.at(1, 1)+matrix1.at(1, 2)*matrix2.at(2, 1);
    int new_12=matrix1.at(1, 1)*matrix2.at(2, 1)+matrix1.at(1, 2)*matrix2.at(2, 2);
    int new_21=matrix1.at(2, 1)*matrix2.at(1, 1)+matrix1.at(2, 2)*matrix2.at(2, 1);
    int new_22=matrix1.at(2, 1)*matrix2.at(2, 1)+matrix1.at(2, 2)*matrix2.at(2, 2);

    return Matrix_2(new_11, new_12, new_21, new_22);
}

Vector_2 operator*(const Matrix_2& matrix, const Vector_2& vector){
    int new_x=matrix.at(1, 1)*vector.x()+matrix.at(1, 2)*vector.y();
    int new_y=matrix.at(2, 1)*vector.x()+matrix.at(2, 2)*vector.y();

    return Vector_2(new_x, new_y);
}

Matrix_2 operator%(const Matrix_2& matrix, const int& nr){
    i64 new_11=matrix.at(1, 1)%nr;
    i64 new_12=matrix.at(1, 2)%nr;
    i64 new_21=matrix.at(2, 1)%nr;
    i64 new_22=matrix.at(2, 2)%nr;

    return Matrix_2(new_11, new_12, new_21, new_22);
}

Matrix_2 calcul(Matrix_2 baza, i64 exp, int nr){
    if(exp==0) return I;

    Matrix_2 result=calcul(baza, exp/2, nr);

    if(exp%2==0) return result*result%nr;

    return result*result%nr*baza%nr;
}

i64 calcul(i64 baza, i64 exp, int nr){
    if(exp==0) return 1;

    i64 result=calcul(baza, exp/2, nr);

    if(exp%2==0) return result*result%nr;

    return result*result%nr*baza%nr;
}

#define NR 666013

int k_fib_mod_NR(i64 k){
    Matrix_2 M=calcul(Matrix_2(1, 1, 1, 0), k, NR);

    return M.at(2, 1);
}

int main(){
    ifstream fin("kfib.in");
    ofstream fout("kfib.out");

    int k;
    fin>>k;

    fout<<k_fib_mod_NR(k);

    return 0;
}