第一次参加CSP,分数不是很高,但是考试之后还是想做一下考题练习一下,感觉第四题思路比第三题更直观一点,所以尝试了一下。题目如下:
题目中给出的测试样例,实测七个中前三个都可以通过,后四个由于样例过大过多,导致Windows Terminal会崩溃,所以无法完成测试。
代码中,操作使用map<int,pair<int,matrix>> op来存储,第一个int表示操作的编号,第二个int表示每个操作中的操作码(1,2,3),matrix为输入的矩阵(当操作码为3时不需要输入矩阵)。当需要输出密码时,deque<pair<int,matrix>> dq用来存储生成密码的矩阵,其中int用来表示存入dq的矩阵的次序先后,matrix表示当前矩阵。下面给出自己的代码(没有经过任何优化,完全顺着题目思路编写):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAX = 998244353;
class matrix
{
private:
array<ll, 4> m;
public:
matrix();
matrix(const array<ll, 4> &op);
matrix &operator=(matrix n);
matrix &operator=(const array<ll, 4> &nm);
matrix &operator*=(const matrix &n); // 模998244353的乘法
matrix &operator%=(const int n);
void show();
};
int main(void)
{
int n, m;
map<int, pair<int, matrix>> op;
deque<pair<int, matrix>> dq;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
int oc;
array<ll, 4> temp1;
cin >> oc;
if (oc == 3)
op.insert(make_pair(i, make_pair(oc, matrix(array<ll, 4>({0, 0, 0, 0})))));
else
{
for (int j = 0; j < 4; j++)
cin >> temp1[j];
matrix temp2(temp1);
op.insert(make_pair(i, make_pair(oc, temp2)));
}
}
for (int i = 1; i <= m; i++)
{
int choice;
cin >> choice;
if (choice == 1)
{
int loc, opcode;
cin >> loc >> opcode;
if (opcode == 3)
op[loc].first = opcode;
else
{
array<ll, 4> temp;
for (int i = 0; i < 4; i++)
cin >> temp[i];
op[loc] = make_pair(opcode, matrix(temp));
}
}
else if (choice == 2)
{
int l, r, cnt = 0;
matrix res({1, 0, 0, 1});
cin >> l >> r;
for (int i = l; i <= r; i++)
{
if (op[i].first == 1)
{
dq.push_front(make_pair(i, op[i].second));
cnt++;
}
else if (op[i].first == 2)
{
dq.push_back(make_pair(i, op[i].second));
cnt++;
}
else if (op[i].first == 3)
{
if (dq.size())
{
if (dq.front().first > dq.back().first)
dq.pop_front();
else
dq.pop_back();
cnt--;
}
}
}
for (int i = 0; i < cnt; i++)
{
res *= dq.front().second;
dq.pop_front();
}
res %= MAX;
res.show();
}
}
return 0;
}
matrix::matrix()
{
m[0] = m[1] = m[2] = m[3] = 0;
}
matrix &matrix::operator=(matrix n)
{
if (this == &n)
return *this;
for (int i = 0; i < 4; i++)
m[i] = n.m[i];
return *this;
}
matrix::matrix(const array<ll, 4> &op)
{
for (int i = 0; i < 4; i++)
m[i] = op[i];
}
matrix &matrix::operator=(const array<ll, 4> &nm)
{
for (int i = 0; i < 4; i++)
m[i] = nm[i];
return *this;
}
matrix &matrix::operator*=(const matrix &n)
{
array<ll, 4> r;
r[0] = ((m[0] * (n.m[0])) % MAX + (m[1] * (n.m[2])) % MAX) % MAX;
r[1] = ((m[0] * (n.m[1])) % MAX + (m[1] * (n.m[3])) % MAX) % MAX;
r[2] = ((m[2] * (n.m[0])) % MAX + (m[3] * (n.m[2])) % MAX) % MAX;
r[3] = ((m[2] * (n.m[1])) % MAX + (m[3] * (n.m[3])) % MAX) % MAX;
*this = r;
return *this;
}
matrix &matrix::operator%=(const int n)
{
for (int i = 0; i < 4; i++)
m[i] %= n;
return *this;
}
void matrix::show()
{
for (int i = 0; i < 4; i++)
std::cout << m[i] << " ";
std::cout << std::endl;
}