Cod sursa(job #2654378)

Utilizator raikadoCri Lu raikado Data 30 septembrie 2020 18:14:26
Problema Al k-lea termen Fibonacci Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.24 kb
#include <fstream>
#include <iostream>

using namespace std;

#define TYPE unsigned long int

class fibmat
{
	TYPE Z[2][2];

public:
	fibmat() : Z{{0,1},{1,1}} {};
	fibmat(TYPE a, TYPE b, TYPE c, TYPE d) : Z{{a,b},{c,d}} {};

	fibmat operator%(int N) const
	{
		return fibmat(Z[0][0] % N, Z[0][1] % N, Z[1][0] % N, Z[1][1] % N);
	}

	fibmat operator*(const fibmat &other) const
	{
		return fibmat(Z[0][0]*other.Z[0][0] + Z[0][1]*other.Z[1][0],
					  Z[0][0]*other.Z[0][1] + Z[0][1]*other.Z[1][1],
					  Z[1][0]*other.Z[0][0] + Z[1][1]*other.Z[1][0],
					  Z[1][0]*other.Z[0][1] + Z[1][1]*other.Z[1][1]);
	}

	TYPE at(int i, int j) {return Z[i][j];}
};

fibmat lgput(const fibmat &Z, long P, long MOD)
{
	if (P == 0) return fibmat(1,0,0,1);
	else if (P == 1) return Z % MOD;
	else if (P % 2 == 0) return lgput((Z*Z) % MOD, P/2, MOD);
	else if (P % 2 == 1) return (Z * lgput((Z*Z) % MOD, P/2, MOD)) % MOD;
	else throw -1;
}

int main(int argc, char const *argv[])
{
	ifstream fin("kfib.in");
	ofstream fout("kfib.out");

	long K; fin >> K;
	const long MOD = 666013;

	// long Z[2][2] = {{0,1},{1,1}};
	// lgput(Z, 0, MOD);
	// cout << (Z[0][1] + Z[1][1]) % MOD << endl;

	fibmat Z = lgput(fibmat(), K-2, MOD);
	fout << (Z.at(0,1) + Z.at(1,1)) % MOD << endl;



	return 0;
}