我们首先给出一些关于楼梯的形式定义。
我们称一对正整数组成的二元组 为格子,称格子构成的集合 (可以为空)为楼梯当且仅当其满足下面两个条件:
对于一个楼梯 和 ,我们定义 为生成格生成的子楼梯为
容易证明这一集合仍然是一个楼梯。对于一个楼梯 ,我们定义边界格数为满足 或 的 的数量。
为了方便理解,我们接下来给出直观解释。我们在平面上可以将所有格子按从左到右 坐标递增、从上到下 坐标递增的顺序排列成网格,因此我们也称 为第 行第 列的格子。
在这一解释下,若一个格子属于某个楼梯,且它上方和左方不是边界,则对应格子也属于这个楼梯。子楼梯就是生成格右下方区域格子所构成的非空楼梯,一个楼梯的边界格数是上边界或左边界上的总格数。
如下图, 组成了一个合法的楼梯。这一楼梯的边界格数为 ,其中以 作为生成格生成的子楼梯的边界格数为 。
长颈鹿看到屏幕上的楼梯后很好奇。他首先计算出了这一楼梯的边界格数 ,并给定了 的某一正整数因子 。他想要知道,给定的楼梯是否有子楼梯满足边界格数等于 。如果是,他希望你给出任一这样的子楼梯的生成格。
梦境时常变化,因此长颈鹿可能会有许多次这样的询问,楼梯也可能会发生变化。初始楼梯 为空,对于 记 为最大的满足 的正整数,若不存在则令其为 ,则有若干次三种之一的修改:
- 给定正整数 和 ,在前 行的末尾插入 格。形式化地,对于 ,将 加入 。
- 给定正整数 和 ,在第 行后(包含第 行)的所有行行末尾删去 格,若不足则删空。形式化地,对于 ,将 从 中移除(不存在的则忽略)。
- 给定正整数 ,撤销之前的 次操作,即将楼梯还原为 次操作前的状态,保证这 次操作均为询问或在行末尾插入。具体地,假设该操作为第 次操作,我们一定有 ,且第 次操作均为询问或在行末尾插入(即上述的第一种修改)。你只需要将楼梯还原为第 次操作前的状态即可(当然,你应该保留询问的输出)。
可以证明每次修改之后得到的集合仍然是一个楼梯。