Cod sursa(job #3235653)

Utilizator rainerretzler rainer Data 19 iunie 2024 20:57:05
Problema Al k-lea termen Fibonacci Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <stdio.h>
#include <stdlib.h>

#define input "kfib.in"
#define output "kfib.out"

//Ghimpău Mihai-Vladimir

void inmultire1x2(long long int rez[1][2], long long int Z[2][2], long long int m)
{
    long long int newRez[1][2];
    int i, j;
    for(j = 0; j<= 1; j++)
    {
        newRez[0][j] = 0;
        for(i = 0; i <= 1; i++)
        {
            newRez[0][j] = (newRez[0][j] + rez[0][i] * Z[i][j]) % m;
        }
    }
    for(j = 0; j <= 1; j++)
    {
        rez[0][j] = newRez[0][j];
    }
}

void inmultire2x2(long long int A[2][2], long long int B[2][2], long long int m)
{
    long long int ans[2][2];
    int i, j, k;
    for (i = 0; i <= 1; i++)
    {
        for (j = 0; j <= 1; j++)
        {
            ans[i][j] = 0;
            for (k = 0; k <= 1; k++)
            {
                ans[i][j] = (ans[i][j] + A[i][k] * B[k][j]) % m;
            }
        }
    }
    for (i = 0; i <= 1; i++)
    {
        for (j = 0; j <= 1; j++)
        {
            A[i][j] = ans[i][j];
        }
    }
}

int main(void)
{
    FILE *in, *out;
    in = fopen(input, "r");
    out = fopen(output, "w");

    long long int k, m = 666013, Z[2][2], M[1][2];
    fscanf(in, "%lld", &k);
    Z[0][0] = 0;
    Z[0][1] = 1;
    Z[1][0] = 1;
    Z[1][1] = 1;
    M[0][0] = 0;
    M[0][1] = 1;
    while(k)
    {
        if(k % 2)
        {
            inmultire1x2(M, Z, m);
            k--;
        }
        else
        {
            inmultire2x2(Z, Z, m);
            k /= 2;
        }
    }
    fprintf(out, "%lld", M[0][0]);

    fclose(in);
    fclose(out);
    return 0;
}