Cnoi2020 领域极限
应该是最简单的做法,同时也是 AT 官方题解做法。
考虑计算 \(\min\sum\limits_{1\le i\le j\le n}|a_i-a_j|\),乘二即为答案。
考虑 \(n\) 个线段中使 \(l_x\) 最大的 \(x\) 以及使 \(r_y\) 最小的 \(y\)。
- 若 \(l_x\le r_y\),那么 \(\forall i\in [1,n],l_i\le l_x,r_i\ge r_y\),则 \(a_i\) 取 \([l_x,r_y]\) 之间的任意数即可,答案为 \(0\)。
- 否则 \(l_x>r_y\),画图发现此时任意 \([l_i,r_i]\) 都与 \([r_y,l_x]\) 有交。所以任意的 \(a_i\) 都能取到 \([r_y,l_x]\) 之间的某个值。所以 \(|a_i-a_x|+|a_i-a_y|=|a_x-a_y|\)。
那么我们把 \([r_y,l_x]\) 的贡献拎出来单独考虑,设剩下的 \(n-2\) 个 \(l_{\max},r_{\min}\) 的贡献为 \(T\),此时的答案为:
\[\begin{aligned}&T+|a_x-a_y|+\sum\limits_{i\neq x,y}(|a_i-a_x|+|a_i-a_y|)\\=\quad&T+(n-1)|a_x-a_y|\end{aligned}
\]
由于 \(a_x,a_y\) 对后续的统计没有影响了,直接令 \(a_x=l_x,a_y=r_y\):
\[\text{ans}=T+(n-1)(l_x-r_y)
\]
所以我们每次拿出一个 \(l_{\max},r_{\min}\),计算这对 \(l,r\) 的贡献,然后再把这对 \(l,r\) 从数组中删去,不断重复这个过程直到 \(l_{\max}\le r_{\min}\) 即可。
因为这个过程中 \([r_{\min},l_{\max}]\) 这个区间始终是不断缩紧的,所以每个剩下的 \(a_i\) 都能满足在任意时刻能取在 \([r_{\min},l_{\max}]\) 之间。
复杂度 \(O(n\log n)\),瓶颈在于排序。
const int N = 3e5 + 300;
int n, l[N], r[N];
int main() {
n = rd();
for (int i = 1; i <= n; i++)
l[i] = rd(), r[i] = rd();
sort(l + 1, l + n + 1, greater<int> ());
sort(r + 1, r + n + 1);
ll res = 0;
for (int i = 1; i <= n; i++) {
if (l[i] <= r[i]) break;
res += 1ll * (l[i] - r[i]) * (n - 2 * i + 1);
}
wr(res * 2);
return 0;
}