Pagini recente » Cod sursa (job #1064286) | Cod sursa (job #799106) | Cod sursa (job #996512) | Cod sursa (job #1487542) | Cod sursa (job #2264126)
#include <iostream>
#include <vector>
#include <cassert>
#include <fstream>
using std::vector;
using std::cout;
uint64_t mul_mod(uint64_t a, uint64_t b, uint64_t m)
{
uint64_t d = 0, mp2 = m >> 1;
int i;
if (a >= m) a %= m;
if (b >= m) b %= m;
for (i = 0; i < 64; ++i)
{
d = (d > mp2) ? (d << 1) - m : d << 1;
if (a & 0x8000000000000000ULL)
d += b;
if (d >= m) d -= m;
a <<= 1;
}
return d;
}
class Matrix
{
private:
vector< vector<int> > A;
unsigned int rows, columns;
public:
Matrix(unsigned int size) {
A = vector< vector<int> >(size, vector<int>(size, 0));
rows = columns = size;
}
Matrix(unsigned int r, unsigned int c) {
A = vector< vector<int> >(r, vector<int>(c, 0));
rows = r;
columns = c;
}
Matrix(vector< vector<int> > x) {
A = x;
rows = x.size();
columns = x[0].size();
}
const unsigned int getRows() {
return rows;
}
const unsigned int getColumns() {
return columns;
}
vector<int>& operator[](int x) {
return A[x];
}
Matrix operator=(Matrix other) {
rows = other.rows;
columns = other.columns;
A = other.A;
return *this;
}
Matrix operator=(vector< vector<int> > vec) {
A = vec;
rows = vec.size();
columns = vec[0].size();
return *this;
}
const Matrix operator+(Matrix other) {
Matrix aux(rows, columns);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
aux[i][j] = A[i][j] + other[i][j];
}
}
return aux;
}
const Matrix operator-(Matrix other) {
Matrix aux(rows, columns);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
aux[i][j] = A[i][j] - other[i][j];
}
}
return aux;
}
const Matrix operator*(Matrix other) {
assert(columns == other.rows);
int n = rows, m = other.columns;
Matrix aux(n, m);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int sum = 0;
for (int k = 0; k < columns; k++) {
sum += A[i][k] * other[k][j];
}
aux[i][j] = sum;
}
}
return aux;
}
const Matrix multiply_with_modulo(Matrix other, int modulo) {
assert(columns == other.rows);
int n = rows, m = other.columns;
Matrix aux(n, m);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int sum = 0;
for (int k = 0; k < columns; k++) {
sum += mul_mod(A[i][k], other[k][j], modulo);
}
aux[i][j] = sum;
}
}
return aux;
}
// ( 1 2 9 8 ) ( 1 2 3 )
// ( 5 2 5 2 ) ( 3 2 1 )
// ( 7 9 1 1 ) * ( 7 3 4 ) = ?
// ( 2 2 2 2 ) ( 9 1 2 )
// ( 1 5 4 3 )
// Concluzie: 5|4 * 4|3 = 5|3
// ( 142 41 67 ) (1*1+2*3+9*7+8*9 1*2+2*2+9*3+8*1 1*3+2*1+9*4+8*2)
// ( 64 31 41 )
// ( )
// ( )
// ( )
const Matrix operator/(Matrix other) {
std::cerr << "YOU MORON!" << '\n';
assert(false); // You dun goofed!
}
};
template<typename T>
T raise_to_power(T init, int power) {
if (power == 1) return init;
if (power % 2 != 0) return init * raise_to_power(init, power - 1);
T rez = init * init;
return raise_to_power(rez, power / 2);
}
template<typename T>
T raise_to_power_modulo(T init, int power, int modulo = 666013) {
if (power == 1) return init;
if (power % 2 != 0) return init * raise_to_power(init, power - 1);
T rez = init.multiply_with_modulo(init, modulo);
return raise_to_power(rez, power / 2);
}
std::ifstream fin("kfib.in");
std::ofstream fout("kfib.out");
int main() {
int k;
fin >> k;
Matrix Z = { { {0,1},{1,1} } };
Matrix M1 = {{{0, 1}}};
//Matrix Mk = M1 * raise_to_power_modulo(Z, k - 1, 666013);
Matrix Mk = M1 * raise_to_power(Z, k - 1);
fout << Mk[0][1] << '\n';
return 0;
}