第二分块 题解
第二分块。
我们观察一下这个查询操作。把所有大于
我们令
若
若
我们发现不管怎么操作,这个
所以我们如果是对全局进行修改,按照上面的分析,只需要枚举需要修改的那些数值即可。这里枚举的数值的总和为
我们希望对每个不同的值的修改能做到
考虑使用并查集把相同的值并起来。那么修改的时候,只需要把修改前值对应的并查集的根,连到修改后的值的并查集的根上即可。同时我们需要记录每个数的出现次数,修改的时候直接加过去就好了。
这里有一些很好的性质:我们每次用来连接的都是并查集的根,而一个根连到另一个根之后,这个值本身就消失了。而且我们在这里并不用这个并查集查询。因此这里的并查集并不会进行路径压缩,是
然后如果是查询全局某个数的出现位置,那么直接
我们考虑查询所有位置的实际值。这里就需要用到并查集的找父亲的操作了。由于这里访问了并查集的所有位置,并进行了路径压缩,所以总复杂度是
到这里,接下来的步骤就非常明显了。我们对序列进行分块。
对于一个块的全局修改、全局查询,我们直接按照上述方式去做即可,总时间复杂度
对于一个块的部分修改,我们先暴力把每个位置的实际值还原,然后对块进行重构即可。单次
对于一个块的部分查询,我们直接使用并查集找到每个位置的实际值,然后判断是否相等即可。单次不超过
总时间复杂度
我们来分析空间复杂度。我们需要对每个块记录每个数的出现次数,那么至少需要一个
不过我们可以发现,我们在分块的时候,块是独立的,块与块之间不会相互影响。所以我们可以将操作离线,对每个块都按顺序处理一遍所有的操作,然后把询问的答案累加即可。
这样我们只需要开一个块需要使用的空间,然后共用这些空间即可。
所以空间复杂度