Cod sursa(job #2182498)

Utilizator NicoletatircomnicuTircomnicu Nicoleta Nicoletatircomnicu Data 22 martie 2018 13:41:48
Problema Iepuri Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;

#define MOD 666013
#define KMAX 3

class Task {
public:
    void solve() {
        rezolvare();
    }

private:
    long long n, x, y, z, a, b, c, n1;
    int C[3][3];

    void rezolvare() {
        //ifstream fin("/home/nico/CLionProjects/iepure/iepuri.in");
        //ofstream fout("/home/nico/CLionProjects/iepure/iepuri.out");
        ifstream fin("iepuri.in");
        ofstream fout("iepuri.out");
        fin >> n;

        for (int i = 1; i <= n; i++) {
            fin >> x >>y >>z>>a>>b>>c>>n1;
            C[0][0] = a;
            C[0][1] = b;
            C[0][2] = c;
            C[1][0] = 1;
            C[1][1] = 0;
            C[1][2] = 0;
            C[2][0] = 0;
            C[2][1] = 1;
            C[2][2] = 0;
            fout << get_result()<<"\n";
        }
        fout.close();
        fin.close();
    }
    // 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 ca suma  incape pe 64 de biti

                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;                       // ramane de calculat C^(p/2)
            } else {
                // reduc la cazul anterior:
                multiply_matrix(tmp, C, tmp); // tmp = tmp*C
                --p;                          // ramane de calculat C^(p-1)
            }
        }

        // avem o parte din rezultat in C si o parte in tmp
        multiply_matrix(C, tmp, R);           // rezultat = tmp * C
    }

    int get_result() {
        power_matrix(C, (n1-2), C);

        int sol = (((1LL * C[0][0] * z)%MOD + (1LL * C[0][1] * y)%MOD)%MOD +(1LL *C[0][2] * x)%MOD)%MOD;
        return sol;
    }
};

int main() {
    Task task;
    //cout <<"dfjsdgf"<<endl;
    task.solve();
    return 0;
}