NOIP 模拟赛:2024-11-27

T1T2 有点无脑了。T3T4 有点抽象了。

T3:

T4:

给定\(n\)长度的序列\(a_1,a_2,\cdots,a_n\)。你可以进行下面两种操作

  1. 选择整数\(i(1\le i \le n)\),然后将\(a_i\)变为\(a_i+2\)
  2. 选择整数\(i(1\le i \le n)\),然后将\(a_i\)变为\(a_i-1\)

你的目标是将其变为“特殊等差数列”,这要求存在整数\(d\)使得至少有\(n-2\)个整数\(i(2\le i \le n)\),满足\(a_i-a_{i-1}=d\)

每一次你可以选择两种操作中的任意一种,求最少的操作总次数以达到目标。\(n\le 10^5\)

草了,一直在差分数组上想。

如果手玩了几组 \(n=20\) 的样例,发现 \(|d|\) 其实很小。仔细分析可以得到应该有 \(n\cdot d\le 2\times 10^6\)(其实题目数据里 \(n\cdot d\le 2\times 10^5\))。

这启示我们 \(O(n\cdot d\cdot \log n)\) 是可行的,也就是可以枚举 \(d\) 然后 \(O(n\log n)\) 检验。

对于固定的 \(d\),只需要决定两个部分的首项是多少。对每个前缀求出最小代价,翻转一下序列再求一遍(其实是对每个后缀求出最小代价),拼起来即可。(能这么做是因为发现一个序列数整体平移或取相反数,答案不变)

考虑令 \(b_i=a_i-(i-1)\cdot d\),只需要决策点 \(x\)\(b_i\rightarrow x\) 的步数和最小即可。容易想到 \(x\) 应该取当前前缀排名 \(\dfrac{2}{3}\) 小的数或其 \(\pm 1\)。用对顶堆维护即可。

posted @ 2024-11-28 16:11  FLY_lai  阅读(34)  评论(0)    收藏  举报