uoj671 诡异操作
这是经典套路吗?为什么胡策的题解里全是“应用 uoj671 的经典套路”这种话?
下文令 \(w=128\)。
一个很经典的分析是每个数至多会被操作 \(O(w^2)\) 次就会变成 \(0\)。因此若直接线段树维护是 \(O(nw^2\log n)\)。考虑特殊性质,我们声称对于 sub2 和 sub4(两个特殊性质),这种做法的复杂度为 \(O(nw+q\log n)\)。
考虑对于线段树上的每一个节点,完全包含节点维护区间的修改数只有 \(O(w)\) 个。因此相较于普通的带标记的线段树,每个节点只会额外贡献 \(O(w)\) 的代价,根据总节点数为 \(O(n)\),不难得到 \(O(nw+q\log n)\) 的时间复杂度分析。
期望得分 \(55\) 分。
考虑在线段树上打标记,除法打标记看上去很难维护,我们对与操作打标记,具体来说,每个节点上维护一个长为 \(w\) 的数组,第 \(i\) 位代表区间内有多少的二进制包含 \(2^i\)。信息合并的时间复杂度为 \(O(w)\)。这样一次询问的时间复杂度就是 \(O(w\log n)\),对于一次操作二,我们维护懒标记代表将某些位置全部变成 \(0\),这样操作二的复杂度为 \(O(w\log n)\)。对于操作一,像上文一样暴力做,这样遍历到的节点数量为 \(O(nw+q\log n)\),总时间复杂度 \(O(nw^2+qw\log n)\)。
期望得分 \(55\) 分。
上述做法的问题在于信息合并/下放的复杂度太大。考虑上面做法中长为 \(w\) 的那个数组,如果将其列成一个表格的话(每行存储数组中每个数的二进制位),可以发现表格大小是 \(\log n\times w\) 的,这启发我们对表格“转置”,即用 \(\log n\) 个数维护每一列,这样标记上传不难直接模拟加法做到 \(O(\log n)\),标记下放等价于将某几行的数清零,也可以压位之后 \(O(\log n)\) 解决。算答案的话可以对于每个询问支付额外的 \(O(w)\) 的代价或者其它方法解决。
考虑一下时间复杂度,不难发现就是上面做法中的标记合并/下放变成了 \(O(\log n)\),因此时间复杂度为 \(O(nw\log n+q\log n^2)\)。不过可以分析到更低一步的复杂度,注意到标记合并/下放的复杂度为 \(O(\log len)\) 而并非 \(O(\log n)\)(\(len\) 为该区间长度),而 \(\sum \log n\) 这类式子可以分析到 \(O(n)\),因此总时间复杂度 \(O(nw+q\log n^2)\),从不同实现出发可能会有 \(O(nw+q\log n^2+qw)\) 的时间复杂度。
期望得分 \(100\) 分。

浙公网安备 33010602011771号