今天是真的不颓。
T1 如果说有这样的 a = { 1 , 2 } a = \{1,2\} a = { 1 , 2 } 和 b = { 100 , 101 } b = \{100,101\} b = { 100 , 101 } ,显然我们不能先加 a 1 a_1 a 1 ,而应该先加 a 2 a_2 a 2 。而后又看到 x x x 可以为负,想到如果说将 a i a_i a i 加上 x x x 使得 a i = b i a_i = b_i a i = b i 且 a i > a i + 1 a_i > a_{i + 1} a i > a i + 1 ,我们就连一条 i + 1 → i i + 1 \to i i + 1 → i 的边。可以证明这是一个有向无环图。因此我们一定有用 ∑ i = 1 n [ a i ≠ b i ] \sum\limits_{i = 1}^{n}[a_i \ne b_i] i = 1 ∑ n [ a i = b i ] 次的方法使得 a = b a = b a = b 。
现在我们考虑使代价更小。考虑对于一个 ( a i − b i ) 2 (a_i - b_i)^2 ( a i − b i ) 2 ,要使它变小,我们考率分多次。显然等分最优。赛时想到了做背包 dp,复杂度 O ( n m 2 ) O(nm^2) O ( n m 2 ) 。可以拿到 50 \color{#5ec05e}{50} 50 的好成绩。看这个绿色就知道确实很好。
正解是整一个大根堆。将每个 ( a i − b i ) 2 (a_i - b_i)^2 ( a i − b i ) 2 多分一个的负贡献插入,比如初始就放每个 ( a i − b i ) 2 (a_i - b_i)^2 ( a i − b i ) 2 从 1 1 1 次到 2 2 2 次的负贡献。取 m − ∑ i = 1 n [ a i ≠ b i ] m - \sum\limits_{i = 1}^{n}[a_i \ne b_i] m − i = 1 ∑ n [ a i = b i ] 次就好。
没放代码是因为下次再做的时候希望能自己写出来。
T2 听 HD0X 讲的。
看到冒泡排序,想到逆序对。离线,从大到小枚举 i i i ,并枚举每个 x = i x = i x = i 的查询,计 u u u 表示 i i i 位置前面的比它大的数量,v v v 表示 i i i 位置后面的比它大的数量。让我们分类讨论一下(下文的 k k k 都指查询的 k k k ,i d id i d 指查询编号,p o s i pos_i p o s i 指 i i i 的原位置):
k ≤ u k \le u k ≤ u 这样的话,i i i 前面的会在 k k k 次冒泡后跑到 i i i 后面去并把 i i i 往前挤,a n s i d = p o s i − k ans_{id} = pos_i - k an s i d = p o s i − k 。k ≤ u + v k \le u + v k ≤ u + v 从头开始考虑 k k k 次冒泡。每次冒泡,一定会有一个比 i i i 更大的数 P j P_j P j 被一个更大的数 P j + 1 P_{j + 1} P j + 1 堵住,且位置比 P j + 1 P_{j + 1} P j + 1 左一个。 我们掏个样例出来:{ 4 , 3 , 5 , 1 , 2 } \{4,3,5,1,2\} { 4 , 3 , 5 , 1 , 2 } 。我们想要查询 3 3 3 在第 2 2 2 次冒泡后的位置。 第 1 1 1 次冒泡:{ 3 , 4 , 1 , 2 , 5 } \{3,4,1,2,5\} { 3 , 4 , 1 , 2 , 5 } ,4 4 4 被 5 5 5 堵住,位置 − 1 -1 − 1 。 第 2 2 2 次冒泡:{ 3 , 1 , 2 , 4 , 5 } \{3,1,2,4,5\} { 3 , 1 , 2 , 4 , 5 } ,3 3 3 被 4 4 4 堵住,位置 − 1 -1 − 1 。 这样我们看到 3 3 3 在 1 1 1 的位置。这个 1 1 1 是由 5 5 5 最初的位置经过 2 2 2 次 − 1 -1 − 1 后得到的。 我们再掏一个样例:{ 3 , 4 , 2 , 5 , 1 } \{3,4,2,5,1\} { 3 , 4 , 2 , 5 , 1 } 。我们想要查询 2 2 2 在第 3 3 3 次冒泡后的位置。 第 1 1 1 次冒泡:{ 3 , 2 , 4 , 1 , 5 } \{3,2,4,1,5\} { 3 , 2 , 4 , 1 , 5 } ,4 4 4 被 5 5 5 堵住,位置 − 1 -1 − 1 。 第 2 2 2 次冒泡:{ 2 , 3 , 1 , 4 , 5 } \{2,3,1,4,5\} { 2 , 3 , 1 , 4 , 5 } ,3 3 3 被 4 4 4 堵住,位置 − 1 -1 − 1 。 第 3 3 3 次冒泡:{ 2 , 1 , 3 , 4 , 5 } \{2,1,3,4,5\} { 2 , 1 , 3 , 4 , 5 } ,2 2 2 被 3 3 3 堵住,位置 − 1 -1 − 1 。2 2 2 在 1 1 1 的位置。这个 1 1 1 是由 5 5 5 最初的位置经过 3 3 3 次 − 1 -1 − 1 得到的。 我们发现,因为在这 k k k 次里会被堵 k k k 次,所以最初的位置(就是上文的 5 5 5 的最初的位置)一定是比 i i i 大的数按照原序列的顺序的第 k k k 个。而每次被堵会使得下标 − 1 -1 − 1 ,所以答案就是比 i i i 大的数的第 k k k 个的位置减 k k k 。k > u + v k > u + v k > u + v 显然这个时候 i i i 归位了,a n s i d = n − u − v ans_{id} = n - u - v an s i d = n − u − v 。实现可以这样:因为我们从大到小枚举 i i i ,用线段树维护。每次算完 i i i 都将线段树 p o s i pos_i p o s i 的地方置为 1 1 1 。u u u 就是 [ 1 , p o s i ] [1,pos_i] [ 1 , p o s i ] 的区间和,v v v 就是 [ p o s i , n ] [pos_i,n] [ p o s i , n ] 的区间和。“比 i i i 大的数按照原序列的顺序的第 k k k 个”可以通过线段树上二分找到第 k k k 个 i i i 。因为只有 k > u k > u k > u 时才会询问第 k k k 个,所以第 k k k 个一定在 i i i 原位置的右边。
T3 & T4 补题速度还是太快了一点,没看。
后日谈 之前的考试挂分 50 \color{#ff0000}{50} 50 起步,今天只挂了 10 \color{#5ec05e}{10} 10 分,可喜可贺。
要是 T1 没有被背包误导的话就更好了。好歹有 50 分嘛
今天晚上有 div.3,打不打呢?
日记 周二 4月 08 2025 995 字 · 4 分钟