Cod sursă (job #133126)

Utilizator avatar iulianrotaru Rotaru Iulian iulianrotaru IP ascuns
Problemă 2sah (clasele 11-12) Compilator cpp | 1,33 kb
Rundă Arhiva de probleme Status evaluat
Dată 14 mar. 2015 19:35:15 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);
}