P9117 [春季测试 2023] 涂色游戏 题解

· · 题解

对于每行和每列,分别记录这一整行/列上一次被修改为的值以及修改的时间。最终对于每个数,它对应行和对应列中修改时间靠后的那一行/列的值便是他的值。

int main() {
    multipleTests([&]() {
        dR(int, n, m, q);
        std::vector<int> a(n), b(m), t0(n), t1(m);
        for (int i = 1; i <= q; i++) {
            dR(int, op, x, c), x--;
            if (op == 0)
                a[x] = c, t0[x] = i; // 修改这行的值及时间戳
            else
                b[x] = c, t1[x] = i; // 修改这列的值及时间戳
        }
        for (int i = 0; i < n; i++, writeln())
            for (int j = 0; j < m; j++)
                if (t0[i] > t1[j]) // 比较修改时间
                    io.write(a[i], ' ');
                else
                    io.write(b[j], ' ');
    });
    return 0;
}

你也可以只用两个 unsigned long long 数组,前半部分存时间,后半部分存值,输出时强制转换成 unsigned 可以取值,比较大小可以直接比较。

加上一些快读和快写优化跑到了最优解(官方数据 207ms)。

int main() {
    dR(unsigned, t);
    while (t--) {
        dR(unsigned, n, m, q);
        std::vector<u64> a(n), b(m);
        for (unsigned i = 1; i <= q; i++) {
            dR(unsigned, op, x, c), x--;
            if (op == 0)
                a[x] = (u64(i) << 32) + c;
            else
                b[x] = (u64(i) << 32) + c;
        }
        for (unsigned i = 0; i < n; i++, writeln())
            for (unsigned j = 0; j < m; j++)
                if (a[i] > b[j])
                    io.write(unsigned(a[i]), ' ');
                else
                    io.write(unsigned(b[j]), ' ');
    }
    return 0;
}