源代码:
#include<iostream>
#include<cctype>
#include<iomanip>
using namespace std;
typedef long long ll;
const ll p = 1145141, N = 1e6 + 5;
ll n, q, K, l, r, res, inv[p+1];
ll read() {
ll s = 0;
char ch = getchar();
while (!isdigit(ch))ch = getchar();
while (isdigit(ch)) {
s = (s << 1) + (s << 3) + (ch ^ 48);
ch = getchar();
}
return s;
}
struct ma {
ll m[4][4];
ma() {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
m[i][j] = 0;
}
}
}
ma operator*(const ma& a) {
ma res;
for (int k = 1; k <= K; k++)
for (int i = 1; i <= K; i++)
for (int j = 1; j <= K; j++)
res.m[i][j] = (res.m[i][j] + m[i][k]*a.m[k][j]) % p;
return res;
}
}M[N],resv[N];
//矩阵求逆,约旦高斯求逆
ma ni(ma &a) {
ma b;
ll tmp[4][7];
for (int i = 1; i <= K ; i++)tmp[i][i+K] = 1;
for (int i = 1; i <= K; i++)
for (int j = 1; j <= K; j++)
tmp[i][j] = a.m[i][j];
for (int i = 1; i <= K; i++) {
ll niv = inv[tmp[i][i]];
//将矩阵第i行全体乘以第i个元素的逆元,使得第i行第i个元素变成1;
for (int j = i; j <= 2 * K; j++) {
tmp[i][j] = tmp[i][j] * niv % p;
}
//依次将除了第i行以外的其他行的第i个元素变换成0
for (int j = 1; j <= K; j++) {
if (j != i) {
for (int k = i; k <= 2 * K; k++) {
tmp[j][k] = (tmp[j][k] - tmp[j][i] * tmp[i][k]%p + p) % p;
}
}
}
}
//返回结果
for (int i = 1; i <= K; i++)
for (int j = 1; j <= K; j++)
b.m[i][j] = tmp[i][j + K];
return b;
}
int main() {
n = read(), K = read(), q = read();
inv[1] = 1;
//初始化逆元
for (int i = 2; i <= p; i++)inv[i] = (p - p / i) * inv[i % p] % p;
//初始化单位矩阵
for (int i = 0; i <= 3; i++)M[0].m[i][i] = 1, resv[0].m[i][i] = 1;
//M[i]代表前i个矩阵相乘,resv[i]代表前i个矩阵的逆矩阵相乘
for (int k = 1; k <= n ; k++) {
ma in;
for (int i = 1; i <= K; i++)
for (int j = 1; j <= K; j++)
in.m[i][j] = read();
M[k] = M[k - 1] * in;
resv[k] = ni(in) * resv[k - 1];
}
for (int i = 0; i < q; i++) {
l = read(), r = read();
ma tmp = resv[l - 1] * M[r];
for (int i = 1; i <= K; i++)
for (int j = 1; j <= K; j++)
res ^= tmp.m[i][j];
}
cout << res;
}
题目中说矩阵的元素均为正整数,也就是不存在0。
所以我在高斯求逆的时候没有进行交换。
检查了几遍思路不知道错在哪里,求助大家解答。