题目
题目来源:20200523 模拟赛 T1;(具体版权未知)。
测试链接:咕咕咕
题目背景
小澳最近迷上了考古,他发现秦始皇的兵马俑布局十分有特点,热爱钻研的小澳打算在电脑上还原这个伟大的布局。
题目描述
他努力钻研,发现秦始皇布置兵马俑是有一定规律的。兵马俑阵总共有 (n) 行 (m) 列,秦始皇在布置的时候每次会指定一行或一列,然后指定一个兵种,使得这一行或者这一列上全部放上这一个兵种。如果这一行上以前放过其它的兵种,那么他会拔掉以前的兵种改成现在他命令的兵种。
小澳从秦朝的文献中找到了布置这个方阵的操作顺序,他希望你能告诉他布局完成后整个兵马俑阵是什么样子的。
输入格式
输入文件共 (q+1) 行。
输入文件第 (1) 行包括三个正整数 (n)、(m)、(q),分别表示兵马俑阵的行数和列数,以及秦始皇总的操作数。
接下来 (q) 行,每行三个正整数 (x)、(y)、(z),(x) 表示操作种类:
- 若 (x=1),表示给第 (y) 行((yle n))全部放上 (z) 这个兵种;
- 若 (x=2),则表示给第 (y) 列((yle m))全部放上 (z) 这个兵种。
输出格式
输出文件共 (n) 行,每行 (m) 个整数,分别用空格隔开。表示最后方阵上每个位置放的兵种,如果某个位置没有被操作过输出 (0)。
评测限制
从 matrix.in 中读入,输出到 matrix.out。
评测时间限制 (1000 extrm{ms}),空间限制 (256 extrm{MiB})
数据范围与约定
- 对于 (20\%) 的数据,(nmle 25);
- 对于 (30\%) 的数据,(qle 2000);
- 对于 (100\%) 的数据,(n,mle 1000),(nmle 10^5),(qle 10^6)。
分析
题意是,对于一个矩阵,每一次给一行或一列赋值,后赋值的会覆盖前面赋值的。输出这个矩阵赋值后的结果。
(30 exttt{pts})
这就是一个简单的大暴力,每一次都赋值一遍即可。
(100 exttt{pts})
想到这一点,我们不妨看一看数据范围:(large{qle 10^6})。也就是说,会多次修改同一行或同一列。
那么,我们每一次都赋值就非常慢,而且后面会被覆盖。那怎么办呢?
我们不妨倒过来想:影响一个格子的兵种的因素是什么?显然是横竖分别赋值的兵种中较晚的一个。
所以,有一个思路就非常自然:记录每一行和每一列最后修改的内容和时间。输出每一个格子的时候,检查横竖的最晚时间并输出对应兵种。
事实上,这个做法就是正解。我们只需要在修改的时候打上「Lazy Tag」即可。复杂度 (Theta(nm+q)) 绰绰有余。
Code
这实际上就是一个不折不扣的模拟,所以代码量非常少。
#include <cstdio>
#include <cctype>
using namespace std;
const int max_n = 1000;
struct lin
{
int tim, val;
};
lin row[max_n] = {}, col[max_n] = {};
inline int read()
{
int ch = getchar(), t = 1, n = 0;
while (isspace(ch)) { ch = getchar(); }
if (ch == '-') { t = -1, ch = getchar(); }
while (isdigit(ch)) { n = n * 10 + ch - '0', ch = getchar(); }
return n * t;
}
int main()
{
int n = read(), m = read(), q = read(), opt, id, tid;
for (int i = 0; i < q; i++)
{
opt = read(), id = read() - 1, tid = read();
if (opt & 1)
row[id].tim = i + 1, row[id].val = tid;
else
col[id].tim = i + 1, col[id].val = tid;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (row[i].tim > col[j].tim)
printf("%d ", row[i].val);
else
printf("%d ", col[j].val);
}
putchar('
');
}
return 0;
}
后记
顺带一提,类似的题目还有很多,只不过方法有所不同。
有一些利用了差分,加上线段树优化以后才能通过。而另一些甚至于要用二维线段树才能解决。
所以,这种东西很难类比,因为接近的题目也不一定是相同的做法。