NSDY 似乎的 polylog 做法
似乎在随机下比较快,可以卡。
我们把贡献拆开,得到:
先拆维,然后比如考虑维护 \(x\) 轴。
其中 \(F(r)=\sum_{1\le i<j\le r}|x_i-x_j|\) 可预处理,\(G(l,r)=\sum_{i=1}^{l-1}\sum_{j=l}^r |x_i-x_j|\) 是需要在线维护的核心。
预处理 \(F(r)\)
使用两个树状数组(或线段树)维护值域上的个数和总和。从左到右扫描 \(r\),每次加入 \(x_r\),计算它与前面所有点的距离和:
其中 \(\text{cntL}\) 和 \(\text{sumL}\) 是前面小于等于 \(x_r\) 的个数与和,\(\text{cntG}=r-1-\text{cntL}\),\(\text{sumG}=\text{前缀和}-\text{sumL}\)。累加得到 \(F(r)\),复杂度 \(O(n\log n)\)。
维护 \(G(l,r)\)
采用离线扫描左端点 \(l\),并维护一个线段树,每个位置 \(j\) 存储当前值 \(\text{val}_j = \sum_{i=1}^{l-1} |x_i - x_j|\)。初始时 \(l=1\),所有 \(\text{val}_j=0\)。
当 \(l\) 增加时(即加入新左边点 \(x_l\)),需要对所有 \(j>l\) 更新:\(\text{val}_j \leftarrow \text{val}_j + |x_j - x_l|\)。这个操作需要高效处理,因为 \(|x_j-x_l|\) 依赖于 \(x_j\) 与 \(x_l\) 的大小关系。
线段树设计
每个节点维护以下信息:
- \(sum\):区间内 \(\text{val}\) 的和。
- \(sum_x\):区间内原始 \(x\) 值的和。
- \(max_x, min_x\):区间内原始 \(x\) 的最大最小值。
- \(len\):区间长度。
- 懒标记:\(add\_self\)(每个位置加上自身 \(x\) 的次数),\(add\_const\)(加上常数的累加值)。
更新操作 \(\text{update}(l, r, c)\) 表示对区间 \([l,r]\) 内每个位置加上 \(|x_j - c|\)。递归处理:
- 若当前节点区间完全在更新范围内:
- 如果 \(max_x \le c\),则整个区间应加 \(c - x_j\),即 \(add\_const += c\),\(add\_self -= 1\),同时 \(sum += c \cdot len - sum_x\)。
- 如果 \(min_x \ge c\),则整个区间应加 \(x_j - c\),即 \(add\_const -= c\),\(add\_self += 1\),同时 \(sum += sum_x - c \cdot len\)。
- 否则,递归到左右子节点。
- 若部分重叠,同样递归。
查询时,下推标记后返回区间和。
扫描过程
将所有查询按 \(l\) 分组。对于 \(l=1\) 到 \(n\):
- 处理所有左端点为 \(l\) 的查询:得到 \(G(l,r)\) = 线段树区间 \([l,r]\) 的 \(sum\)。
- 若 \(l<n\),执行 \(\text{update}(l+1, n, x_l)\)。
答案合成
对于每个查询,一维答案为:
对 \(y\) 维同样处理,最终答案 \(\text{ans} = \text{ans}_x + \text{ans}_y\)。
复杂度
- 预处理 \(F\):\(O(n\log n)\)
- 线段树每个更新和查询期望 \(O(\log n)\),总复杂度 \(O((n+q)\log n)\)(实际性能依赖于数据,但可通过节点标记优化)。
此方法利用线段树的分治特性,将动态更新转化为区间标记,实现了对 \(G(l,r)\) 的高效维护。
本人题解:
我们把贡献拆开,得到:
先拆维,然后比如考虑维护 \(x\) 轴。
对于区间 \([l, r]\) 内的 \(k\) 个点(设 \(k = r-l+1\)),我们将该维度的坐标提取出来并升序排列为 \(a_1 \le a_2 \le \dots \le a_k\)。那么我们有:
且有
后半部分是简单的,考虑维护前半部分。
这是一个经典的二维偏序贡献问题。为了消去区间 \([l, r]\) 的左端点 \(l\) 的限制,我们使用离线扫描线,考虑维护一个数组 \(f_r=\sum_{j=1}^r i \cdot x_j\\\)。现在我们求出了 \(f_{r-1}\),看如何转移到 \(f_r\)。我们发现有两部分贡献,第一个是 \(x_r\) 系数的大小产生的,第二个是 \(x_r\) 对其他点系数产生的变化。我们可以用两个 BIT。一个是前缀所有值的和,另一个是前缀所有值的个数。然后分别把答案算上就好了。
然后来考虑维护 \(\sum_{i=1}^{l-1} \sum_{j=l}^r |x_i-x_j|\),然后这个东西是做不了 polylog 的,结束了,这个题有莫队简单写法 link。

浙公网安备 33010602011771号