CF916D Jamie and To-do List

题目描述

为什么我有这么多作业要写??? Jamie 的学校生活变得非常忙碌。他开始忘记自己必须完成的作业,于是决定把这些事情记录在一个任务清单(To-do List)上。他为每个任务分配一个**优先级数值**(数值越小表示越重要),以便决定哪些任务需要投入更多时间。 几天后,Jamie 发现清单实在太长了,他一个人根本管理不过来!作为 Jamie 的好朋友,请帮他写一个程序,支持对任务清单的以下操作: - $ \texttt{set}\ a_i\ x_i$ — 如果任务 $a_i$ 不在清单中,则将其加入并将优先级设为 $x_i$;如果 $a_i$ 已在清单中,则将其优先级修改为 $x_i$。 - $ \texttt{remove}\ a_i$ — 如果任务 $a_i$ 在清单中,则将其移除。 - $ \texttt{query}\ a_i$ — 输出比任务 $a_i$ **更重要**(即优先级数值严格更小)的任务数量。如果 $a_i$ 不在清单中,输出 $-1$。 - $ \texttt{undo}\ d_i$ — 撤销此前 $d_i$ 天内所做的所有更改(不包括进行此操作的当天)。 在第 $0$ 天,任务清单为空。在接下来的 $q$ 天里,Jamie 每天会恰好执行上述四种操作之一。如果操作是 `query`,你必须在进入下一天之前输出查询结果,否则可怜的 Jamie 无法做出合理的决策。

输入格式

第一行包含一个整数 $q$ ($1 \le q \le 10^5$) —— 操作的总天数。 接下来的 $q$ 行描述每天的操作。第 $i$ 行描述 Jamie 在第 $i$ 天进行的操作。每行第一个单词表示操作类型,为 `set`、`remove`、`query` 或 `undo` 之一: - 如果是 **set** 操作:后面跟着一个字符串 $a_i$ 和一个整数 $x_i$ ($1 \le x_i \le 10^9$)。$a_i$ 是任务名称,$x_i$ 是优先级。 - 如果是 **remove** 操作:后面跟着一个字符串 $a_i$。 - 如果是 **query** 操作:后面跟着一个字符串 $a_i$。 - 如果是 **undo** 操作:后面跟着一个整数 $d_i$ ($0 \le d_i < i$),表示需要撤销的天数。 所有任务名称 $a_i$ 仅由小写英文字母组成,长度满足 $1 \le |a_i| \le 15$。 保证最后一个操作一定是 `query`。

输出格式

对于每个 `query` 操作,输出一个整数:优先级数值比 $a_i$ 小的任务数量;如果 $a_i$ 不在清单中,则输出 $-1$。 ### 交互说明 如果当前操作是 `query`,你必须在执行下一个操作之前输出结果并**刷新输出缓冲区**。否则,你可能会得到 `Idleness Limit Exceeded`(空闲超限)的判定。 关于如何刷新输出缓冲区,请参考你所用编程语言的文档。以下是一些常见语言的刷新函数: - C: `fflush(stdout);` - C++: `cout

说明/提示

对于全部数据,$1 \le q \le 10^5,1 \le |a_i| \le 15,1 \le x_i \le 10^9,0 \le d_i < i$,且 $a_i$ 均由小写字母构成。 tips/消歧义:`undo` 操作会撤回之前的 `undo` 操作。