分块 + 堆.
每次操作后,如果区间内最大值 $>A$ , $A$ 就会变成区间内的最大值,并且某些数的位置会变,否则无事发生.
考虑分块,对于整块部分,对每块开一个大根堆维护块内所有元素.
修改时,若块内最大值 $>A$ ,就将把 $A$ 换成它,并且打上标记,表示这一块被元素 $A$ 进行了一次操作.
对于边角部分,修改时将标记下放,然后暴力重构这一块.
按照遍历的顺序从前往后依次处理,每一块 $A$ 被交换后的值就是下一块 $A$ 的初始值.
唯一的问题在于某一块已经有标记时,再加入标记需要怎样处理.
首先注意到,操作的顺序不会影响块内元素最后的值,于是没必要合并标记,可以都存下来,下放标记时一起处理.
每个数显然只可能被最小的数替换一次,后面的都没用了,于是用小根堆来存储标记,下放时用堆顶不断尝试交换.
时间复杂度 $O(n\sqrt n\log \sqrt n)$ ,空间复杂度 $O(n\sqrt n)$ .
1 | //%std |