Cod sursă (job #291382)

Utilizator avatar micutu Andrei Vasile Cont Fraudulent micutu IP ascuns
Problemă 2sah (clasele 11-12) Compilator cpp | 1.53 kb
Rundă Arhiva de probleme Status evaluat
Dată 9 mar. 2017 09:40:35 Scor 100
#include <stdio.h>

#define MOD 100003
typedef long long mat3[3][3];

// Calculează a x b și pune rezultatul în a. Folosește c ca spațiu de manevră.
void mul(mat3 a, mat3 b, mat3 c) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            c[i][j] = 0;
            for (int k = 0; k < 3; k++) {
                c[i][j] += a[i][k] * b[k][j];
            }
        }
    }
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            a[i][j] = c[i][j] % MOD;
        }
    }
}

int main(void) {
    int t, n, k;
    FILE *f = fopen("2sah.in", "r");
    fscanf(f, "%d%d%d", &t, &n, &k);
    fclose(f);
    
    f = fopen("2sah.out", "w");
    if (t == 1) {
        // calculăm 3^(k - 1) prin exponențiere logaritmică
        k--;
        long long answer = 1, pow = 3;
        while (k) {
            if (k & 1) {
                answer = (answer * pow) % MOD;
            }
            pow = pow * pow % MOD;
            k >>= 1;
        }
        fprintf(f, "%lld\n", answer);
    } else {
        // calculăm pow^(n + 1 - k) prin exponențiere logaritmică
        k = n + 1 - k;
        mat3 pow = { { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 1 } };
        mat3 ans = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
        mat3 tmp;
        while (k) {
            if (k & 1) {
                mul(ans, pow, tmp);
            }
            mul(pow, pow, tmp);
            k >>= 1;
        }
        fprintf(f, "%lld\n", ans[2][2]);
    }
    fclose(f);
}