分块.
简单转化一下题意,就是求有多少个位置的斜率,在对应前缀中是严格最大的.
每一块维护 $len(x)$ 表示若第一个选中的是块内第 $x$ 个元素,则该块内总共被选的个数.
为了找出块内是哪个元素被选中,还要对每一块维护前 $x$ 个数中的最大值 $mx(x)$ .
修改时将那一块重构一下,回答询问时从第一块开始跳,二分找出下一块中第一个选中的位置.
每跳一块,当前的数就会和块内的最大值取 $\max$ .
设块的大小为 $S$ ,则单次操作的时间复杂度为 $O(S+\frac{n}{S}\cdot\log_2 S)$ ,需要手动调下参数.
为了避免精度出现问题,可以把分子分母记下来,每次比较的时候比较两个分数.
1 | //%std |