Cod sursa(job #3042162)

Utilizator LucianPandelicaPandelica Lucian LucianPandelica Data 4 aprilie 2023 11:48:27
Problema Iepuri Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <bits/stdc++.h>
using namespace std;

#define MOD 666013
#define KMAX 3

int T, X, Y, Z, a, b, c, n;

ifstream f("iepuri.in");
ofstream g("iepuri.out");
 
// C = A * B
void multiply_matrix(int A[KMAX][KMAX], int B[KMAX][KMAX], int C[KMAX][KMAX]) {
    int tmp[KMAX][KMAX];
 
    // tmp = A * B
    for (int i = 0; i < KMAX; ++i) {
        for (int j = 0; j < KMAX; ++j) {
            unsigned long long sum = 0; // presupun că suma încape pe 64 de biți
 
            for (int k = 0; k < KMAX; ++k) {
                sum += 1LL * A[i][k] * B[k][j];
            }
 
            tmp[i][j] = sum % MOD;
        }
    }
 
    //  C = tmp
    memcpy(C, tmp, sizeof(tmp));
}
 
// R = C^p
void power_matrix(int C[KMAX][KMAX], int p, int R[KMAX][KMAX]) {
    // tmp = I (matricea identitate)
    int tmp[KMAX][KMAX];
    for (int i = 0; i < KMAX; ++i) {
        for (int j = 0; j < KMAX; ++j) {
            tmp[i][j] = (i == j) ? 1 : 0;
        }
    }
 
    while (p != 1) {
        if  (p % 2 == 0) {
            multiply_matrix(C, C, C);     // C = C*C
            p /= 2;                       // rămâne de calculat C^(p/2)
        } else {
            // reduc la cazul anterior:
            multiply_matrix(tmp, C, tmp); // tmp = tmp*C
            --p;                          // rămâne de calculat C^(p-1)
        }
    }
 
    // avem o parte din rezultat în C și o parte în tmp
    multiply_matrix(C, tmp, R);           // rezultat = tmp * C
}
 
int iepuri(int n) {
    
    // cazurile de bază
    if (n == 0) 
        return X;
    
    if (n == 1)
        return Y;
    
    if (n == 2)
        return Z;
 
    // construiesc matricea C
    int C[KMAX][KMAX] = { {0, 0, c},
                          {1, 0, b},
                          {0, 1, a} };
   // vreau să aplic formula S_n = S_3 * C^(n-3)
   
   // C = C^(n-3)
   power_matrix(C, n - KMAX + 1, C);
 
   // sol = S_3 * C = dp[n] (se află pe ultima poziție din S_n,
   // deci voi folosi ultima coloană din C)
   int sol = X * C[0][2] + Y * C[1][2] + Z * C[2][2];

   return sol % MOD;
}

int main() {

    int i;
    f>>T;

    for(i = 0; i < T; i++) {
        f>>X>>Y>>Z>>a>>b>>c>>n;
        g<<iepuri(n)<<endl;
    }

    return 0;
}