QOJ.ac

QOJ

حد الوقت: 2.0 s حد الذاكرة: 256 MB مجموع النقاط: 100

#12555. 冰山订单

الإحصائيات

你正在为 Metagonia 证券交易所工作。最近,Metagonia 的交易员们听说了伦敦证券交易所交易的“冰山指令”(Iceberg orders),并要求你的雇主也增加此项功能。证券交易所是一个接收订单并生成交易的引擎。

冰山指令是一个包含五个整数的元组 $(ID, T, P, V, TV)$。每个订单都有一个标识符 $ID$(在所有订单中唯一)、类型 $T$($T=1$ 表示 $BUY$ 买入,或 $T=2$ 表示 $SELL$ 卖出)、价格 $P$、总剩余量 $V$ 和显示量 $TV$。对于每个订单,交易所还会额外记录其当前量 $CV$ 和优先级 $PR$。交易所的订单簿(order book)是一组订单的集合。

交易所生成的交易是包含四个整数的元组 $(BUY\_ID, SELL\_ID, P, V)$。每笔交易都有 $BUY\_ID$ 和 $SELL\_ID$(匹配的买入和卖出订单的标识符)、交易价格 $P$ 以及交易量 $V$。

当交易所收到一个订单时,它会与订单簿中现有的订单进行匹配。具体过程如下:假设收到一个订单 $a$,其类型为 $T_a = SELL$。在订单簿的所有现有订单中,我们寻找满足 $T_b = BUY$ 且 $P_b \ge P_a$ 的订单 $b$。我们选择其中价格最高的订单 $b$;如果存在多个,则选择优先级最小的一个。如果存在这样的订单 $b$,则生成一笔交易 $t$,其中 $BUY\_ID_t = ID_b$,$SELL\_ID_t = ID_a$,交易价格 $P_t = P_b$,交易量 $V_t = \min(V_a, CV_b)$。$V_a$、$V_b$ 和 $CV_b$ 均减去交易量。如果交易后 $V_b = 0$,则将订单 $b$ 从订单簿中移除。如果 $CV_b = 0$(但 $V_b > 0$),则将订单 $b$ 的当前量更新为 $CV_b = \min(V_b, TV_b)$,设置 $PR_b = GP$,并将 $GP$ 加 1。我们继续执行选择 $b$ 并生成交易的操作,直到 $V_a = 0$ 或者订单簿中没有满足条件的订单 $b$ 为止。在后一种情况下,我们将订单 $a$ 加入订单簿,设置 $CV_a = \min(V_a, TV_a)$ 和 $PR_a = GP$,然后将 $GP$ 加 1。当订单 $a$ 的匹配过程结束时,如果订单 $a$ 和 $b$ 之间存在多笔交易(可能有很多笔!),它们将被合并为一笔交易,其交易量等于各笔交易量之和。

如果 $T_a = BUY$,我们寻找满足 $T_b = SELL$ 且 $P_b \le P_a$ 的订单 $b$,并从中选择价格最低且优先级最小的订单 $b$。其余匹配过程与上述相同,交易满足 $BUY\_ID_t = ID_a$,$SELL\_ID_t = ID_b$,$P_t = P_b$,$V_t = \min(V_a, CV_b)$。

初始时订单簿为空。你将依次收到多个订单。你需要打印生成的交易,并在处理完所有订单后打印订单簿的状态。

提示:优先级和 $GP$ 仅用于形式化描述算法。实际实现中无需跟踪优先级。通常,交易所只需在订单簿中为每个价格维护一个按优先级排序的订单列表。

输入格式

第一行包含订单数量 $n$ ($1 \le n \le 50\,000$)。接下来的 $n$ 行每行代表一个订单。每个订单由空格分隔的五个整数 $ID\ T\ P\ V\ TV$ 给出,其中 $1 \le ID \le 1\,000\,000$,$T=1$ 表示 $BUY$,$T=2$ 表示 $SELL$,$1 \le P \le 100\,000$ 且 $1 \le TV \le V \le 1\,000\,000\,000$。

输出格式

对于每个订单,打印处理该订单时生成的所有交易,按 $(BUY\_ID, SELL\_ID)$ 对的升序排列,每笔交易占一行。每笔交易应打印为由空格分隔的四个整数 $BUY\_ID\ SELL\_ID\ P\ V$。保证交易总数不超过 $100\,000$。在所有交易后打印一个空行,随后打印订单簿。订单簿中剩余的每个订单应打印为由空格分隔的六个整数 $ID\ T\ P\ V\ TV\ CV$,先按 $P$ 排序,再按 $PR$ 排序。

样例

输入 1

7
42 1 100 200 20
239 1 100 50 50
1111 1 101 30 15
1234 1 100 300 15
4321 2 99 125 25
5678 1 101 30 30
8765 2 101 100 20

输出 1

42 4321 100 30
239 4321 100 50
1111 4321 101 30
1234 4321 100 15
5678 8765 101 30

42 1 100 170 20 10
1234 1 100 285 15 15
8765 2 101 70 20 20

Discussions

About Discussions

The discussion section is only for posting: General Discussions (problem-solving strategies, alternative approaches), and Off-topic conversations.

This is NOT for reporting issues! If you want to report bugs or errors, please use the Issues section below.

Open Discussions 0
No discussions in this category.

Issues

About Issues

If you find any issues with the problem (statement, scoring, time/memory limits, test cases, etc.), you may submit an issue here. A problem moderator will review your issue.

Guidelines:

  1. This is not a place to publish discussions, editorials, or requests to debug your code. Issues are only visible to you and problem moderators.
  2. Do not submit duplicated issues.
  3. Issues must be filed in English or Chinese only.
Active Issues 0
No issues in this category.
Closed/Resolved Issues 0
No issues in this category.