제출 #9219

#제출 시각아이디문제언어결과실행 시간메모리
9219lemonsqueezeQuaternion inverse (kriii2_Q)C++98
4 / 4
424 ms1088 KiB
#include <stdio.h>
#include <algorithm>
using namespace std;

long long M;
long long A[4][4];
long long B[4];
long long x[4];

const int n=4;

long long getpow (long long x, long long b)
{
	if (b==0) return 1;
	if (b==1) return x;

	long long res = getpow (x, b/2);
	res = (res * res) % M;

	if (b&1) return (res * x) % M;
	return res;
}

long long getinv (long long x)
{
	// x^(M-1) = 1
	// return x^(M-2)

	return getpow (x, M-2);
}

void solve ()
{
	int l = 0;

	for (int i=0; i<n; i++) {
		for (int j=l; j<n; j++) {
			if (A[j][i]) {
				for (int k=i; k<n; k++)
					swap (A[l][k], A[j][k]);
				swap (B[l], B[j]);

				break;
			}
		}

		if (A[l][i]) {
			long long inv = getinv (A[l][i]);
			for (int j=i; j<n; j++) A[l][j] = (A[l][j] * inv) % M;
			B[l] = (B[l] * inv) % M;

			for (int j=l+1; j<n; j++) {
				long long m = A[j][i];
				for (int k=i; k<n; k++)
					A[j][k] = (A[j][k] + (M-m) * A[l][k]) % M;
				B[j] = (B[j] + (M-m) * B[l]) % M;
			}

			l++;
		}
	}

	// rank = l

	for (int i=l; i<n; i++) if (B[i]) {
		for (int j=0; j<4; j++) x[j] = 0;
		return;
	}

	for (int i=0; i<n; i++)
		x[i] = 0;

	int f[4];
	for (int i=0; i<l; i++) {
		for (int j=0; j<n; j++) if (A[i][j]) {
			f[i] = j;
			break;
		}
	}

	for (int i=l-1; i>=0; i--) {
		for (int j=f[i]+1; j<n; j++)
			B[i] = (B[i] + (M-x[j]) * A[i][j]) % M;
		x[f[i]] = B[i];
	}
}

int main ()
{
	int t;
	scanf ("%lld%d", &M, &t);
	while (t--) {
		int a, b, c, d;
		scanf ("%d%d%d%d", &a, &b, &c, &d);
		A[0][0] =  a; A[0][1] = -b; A[0][2] = -c; A[0][3] = -d;
		A[1][0] =  b; A[1][1] =  a; A[1][2] = -d; A[1][3] =  c;
		A[2][0] =  c; A[2][1] =  d; A[2][2] =  a; A[2][3] = -b;
		A[3][0] =  d; A[3][1] = -c; A[3][2] =  b; A[3][3] =  a;
		B[0] = 1;
		B[1] = 0;
		B[2] = 0;
		B[3] = 0;

		for (int i=0; i<n; i++) for (int j=0; j<n; j++)
			A[i][j] = (A[i][j] + M) % M;

		solve ();
		printf ("%lld %lld %lld %lld\n", x[0], x[1], x[2], x[3]);
	}

	return 0;
}

/*
5 3
2 3 2 1
3 1 3 2
3 2 4 1
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...