Cod sursa(job #1486768)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 15 septembrie 2015 16:35:09
Problema Al k-lea termen Fibonacci Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
#include<iostream>
#include<fstream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<bitset>
#include<cstring>
#include<queue>
#include<stack>

#define ull unsigned long long
#define ll long long
#define pb push_back
#define FOR(a,b,c) for (int a=b;a<=c; ++a)
#define ROF(a,b,c) for (int a=b;a>=c; --a)
#define MOD 666013

using namespace std;
ifstream f("kfib.in");
ofstream g("kfib.out");
int K;

struct mat { // matrice patratica de ordin 2
    ll a[2][2];
};

mat pow(mat,int);
mat inmultire (mat,mat);

int main()
{
    f>>K;
    if (K==0) {
        g<<0;
    }
    else {
        mat Z;
        Z.a[0][1]=Z.a[1][0]=Z.a[1][1]=1;
        Z.a[0][0]=0;
        mat R;
        R=pow(Z,K+1);
        g<<R.a[0][0];
    }
    f.close();g.close();
    return 0;
}

mat inmultire(mat A,mat B) { // se inmultesc doua matrice si se tine cont de modulo
    mat R;
    FOR (i,0,1) {
        FOR (j,0,1) {
            int nr=0;
            FOR (k,0,1) {
                nr=(nr+(A.a[i][k]*B.a[k][j])%MOD)%MOD;
            }
            R.a[i][j]=nr%MOD;
        }
    }
    return R;
}

mat pow (mat Z,int exp) { // se aplica algoritmul de ridicare la putere in timp logaritmic pe matrice
    mat R; // matrice unitate
    R.a[0][0]=R.a[1][1]=1;
    R.a[0][1]=R.a[1][0]=0;
    while (exp) {
        if (exp%2==1) {
            R=inmultire(R,Z);
        }
        Z=inmultire(Z,Z);
        exp>>=1;
    }
    return R;
}