Cod sursa(job #2182481)

Utilizator BrateSBratescu Stefan BrateS Data 22 martie 2018 13:26:24
Problema Iepuri Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.18 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;

const unsigned long long kMod = 666013;

class input{
public:
    int x,y,z,a,b,c,n;
    input(int x, int y, int z, int a, int b, int c, int n) :
            x(x), y(y), z(z), a(a), b(b), c(c), n(n) {}
};
class Task {
 public:
	void solve() {
		read_input();
		print_output(get_result());
	}

 private:
	int n;
	vector<input*> v;

	void read_input() {
		ifstream fin("iepuri.in");
		fin >> n;
		for (int i = 0, x,y,z,a,b,c,days; i < n; i++) {
			fin >> x >> y >> z >> a >> b >> c >> days;
            auto *input1 = new input(x, y, z, a, b, c, days);
			v.push_back(input1);
		}
		fin.close();
	}

#define KMAX 3
    void multiply_matrix2(int A[KMAX][KMAX], int B[KMAX], int C[KMAX]) {
        int tmp[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];
                }

                tmp[i] = sum % kMod;
            }
        }

        //  C = tmp
        memcpy(C, tmp, sizeof(tmp));
    }
    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 % kMod;
            }
        }

        //  C = tmp
        memcpy(C, tmp, sizeof(tmp));
    }
    void power_matrix(int C[KMAX][KMAX], int p, int R[KMAX][KMAX]) {
        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
    }
	vector<int> get_result() {
        vector<int> result;
        for(auto i : v){//for each input
            int C[3][3] = {
                    {i->a, i->b, i->c},
                    {1, 0 ,0},
                    {0, 1, 0},
            };
            int d[3] = {i->z, i->y, i->x};
            power_matrix(C, i->n ,C);
            multiply_matrix2(C,d,d);
            result.push_back(d[2]);
        }
        return result;
	}

	void print_output(vector<int> result) {
		ofstream fout("iepuri.out");
        for (auto i : result)
            fout << i << "\n";
		fout.close();
	}
};

int main() {
	Task task;
	task.solve();
	return 0;
}