CF702F T-Shirts
有 \(n\) 种 T 恤,每种有价格 \(c_i\) 和品质 \(q_i\)。
有 \(m\) 个人要买 T 恤,第 \(i\) 个人有 \(v_i\) 元,每人每次都会买一件能买得起的 \(q_i\) 最大的 T 恤。一个人只能买一种 T 恤一件,所有人之间都是独立的。
问最后每个人买了多少件 T 恤?如果有多个 \(q_i\) 最大的 T 恤,会从价格低的开始买。
\(n \le 2\times 10^5, c_i , q_i \le 10^9, m \le 2\times 10^5\)。
数据结构
平衡树
势能分析
好不容易写出的鬼畜做法,就被 #55 的 HACK 数据叉掉了。
鬼畜做法
感觉可能是空间太大了。
从小到大考虑物品,然后维护一个分段函数 \(f(x)\) 表示当前有 \(x\) 元,那么最后会有多少件 T 恤,每一个物品都是导致一段前缀函数值不动,然后后面的函数就是 \(f(x)\) 的平移后的图像。
然后考虑维护,可以用可持久化 fhq-treap,在平衡树上面维护区间以及每段区间的答案,每次将该平衡树分裂,然后用之前的平衡树快速合并上来,为了减少空间,可以对于每个节点记一个产生该节点的时间戳。
然后是代码。
于是被 CF #55 叉掉了。
正经做法
将所有询问作为值丢到平衡树中,从大到小考虑物品,对于物品 \(x\),每次都是 \(< c_x\) 的物品不动,然后 \(\ge c_x\) 的物品直接 \(-c_x\) 然后答案 \(+1\) 之后和前面的 \(<c_x\) 的物品进行合并。
因为平衡树的合并必须是要有序的,于是有问题,接着可以发现,只有 \([c_x, 2c_x)\) 的物品会出现问题,这个可以暴力插入,其他的打个标记然后合并即可。
因为暴力插入的部分每个数每次会 \(/2\),根据势能分析可知,每个数最多 \(\log\) 次就会没了,于是复杂度为 \(\mathcal O(n\log n + q\log^2n)\)。
代码。