← 返回编程题库
coding-cumulative-volume-snapshot简单免费版2000ms未尝试

累计成交量快照查询

Cumulative Volume Snapshot

开始编码

撮合引擎打了一整天的成交流后,量化策略组的回测平台需要回答一个反复出现的问题:「截至时刻 t,本品种总共成交了多少股?」 这个查询会被风控复盘、TWAP/VWAP 算法的母单进度跟踪、以及 PnL 重算等多个下游系统反复触发——同一份成交数据可能在一天里被询问几十万次,每次问的 t 都不同。如果每次都重新扫一遍当天所有成交去累加,CPU 很快就被这些聚合烤干了。

请实现 solution(trades: list[tuple[int, int]], queries: list[int]) -> list[int]trades 是按 timestamp 升序排列的成交流,每条形如 (timestamp_ms, volume);同一毫秒内可能出现多笔成交,这些成交的时间戳相等。queries 是一组互不相关的查询时间戳(不保证有序)。对每个 queries[i] = t,返回所有满足 timestamp <= t 的成交量之和;若没有任何成交满足该条件,则返回 0。注意:当 t 正好等于某条成交的时间戳时,该条成交以及同毫秒内所有成交都要被计入

例如 solution([(100, 10), (100, 5), (200, 7), (350, 3)], [50, 100, 150, 200, 400]) 应返回 [0, 15, 15, 22, 25]:在 t=50 时还没发生任何成交,返回 0;t=100 时前两笔都已成交(注意同毫秒的两笔都计入),累计 10 + 5 = 15t=150 时下一笔尚未发生,仍为 15;t=200 时累计 15 + 7 = 22t=400 时全部完成,累计 25。

朴素的 O(n·m) 做法在 10 万条成交 + 10 万次查询的规模下会被卡住。请把成交流预处理成前缀和数组,再用二分查找把每次查询压到 O(log n),整体复杂度 O((n + m) log n)。

约束条件

  • 0 ≤ len(trades) ≤ 100000
  • 0 ≤ len(queries) ≤ 100000
  • 每条 trade 是 `(timestamp: int, volume: int)`,`timestamp` 为毫秒级时间戳
  • `trades` 按 `timestamp` 升序给出;同一时间戳可能出现多条成交(撮合引擎在同毫秒内成交)——所有时间戳等于查询值 `t` 的成交都应被计入累计
  • 1 ≤ volume ≤ 10⁹(每笔成交量为正整数)
  • 0 ≤ timestamp ≤ 10¹⁸
  • 查询时间戳无序,且可以早于第一笔成交、晚于最后一笔、或正好命中某条成交
  • 返回 `list[int]`,长度等于 `len(queries)`,第 i 项是「时间戳 ≤ queries[i] 的所有成交量之和」;若没有任何成交满足,返回 0

样例

Case 1 · statement example

输入: [[[100,10],[100,5],[200,7],[350,3]],[50,100,150,200,400]]

期望: [0,15,15,22,25]

时间戳 100 处有两笔成交 10 和 5——查询 t=100 时它们都被计入,累计 15。t=150 时下一笔(t=200)尚未发生,仍为 15。t=200 加上 7 变成 22。t=400 时全部完成,累计 25。t=50 时还没有任何成交,返回 0。

Case 2 · queries arrive out of order

输入: [[[10,100],[20,200],[30,300]],[30,5,20,100,10]]

期望: [600,0,300,600,100]

查询无序到达:t=30 时三笔全部完成,累计 600;t=5 早于第一笔,返回 0;t=20 时前两笔完成,累计 300;t=100 在所有成交之后,仍是 600;t=10 命中第一笔成交时间戳,累计 100。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · statement example

输入: [[[100,10],[100,5],[200,7],[350,3]],[50,100,150,200,400]]

期望: [0,15,15,22,25]

时间戳 100 处有两笔成交 10 和 5——查询 t=100 时它们都被计入,累计 15。t=150 时下一笔(t=200)尚未发生,仍为 15。t=200 加上 7 变成 22。t=400 时全部完成,累计 25。t=50 时还没有任何成交,返回 0。

Case 2 · queries arrive out of order

输入: [[[10,100],[20,200],[30,300]],[30,5,20,100,10]]

期望: [600,0,300,600,100]

查询无序到达:t=30 时三笔全部完成,累计 600;t=5 早于第一笔,返回 0;t=20 时前两笔完成,累计 300;t=100 在所有成交之后,仍是 600;t=10 命中第一笔成交时间戳,累计 100。