[ARC152C] Pivot

操作可以看成是以一个 \(a_i\) 为中心翻转,那么有如下性质:

  1. 任意时刻极差不变。
  2. 任意时刻做差分绝对值不变,且每一次要么全正要么全负。

由一点可以做转化 \(max(a_i)=min(a_i)+d\),其中 \(d=a_n-a_1\)

由第二点得 \(min(a_i)\) 一定在原来的 \(a_1,a_n\) 中做变化后得到的数中的一个。什么,你要问为什么?因为差分要么全正要么全负,因此可以认为一个线性的函数,自然在端点处取。

考虑 \(a_1\) 可以达到的最小值,\(a_n\) 同理。
手玩一下可以发现是每次可以加上一个 \(2(a_i-a_1)\)。那么如果我们把每一类的 \(2(a_i-a_1)\) 的系数整理并把所有的 \(2(a_i-a_1)\) 写成方程的形式,\(2p_1(a_1-a_1)+2p_2(a_2-a_1)+...+2p_n(a_n-a_1)=d\),根据 Bezout 得到 \(gcd(a_i-a_1)|d\)。又因为最后的 \(a_1\) 是最初的 \(a_1\) 再加上 \(d\),所以最后的 \(a_1\) 的最小值是 \(a_1\ mod\ gcd(a_i-a_1)\)

于是问题就解决了呢。

const int N = 2e5 + 5;
int n, a[N];
int get(int x) {
    int w = 0;
    rep(i, 1, n) w = gcd(w, 2 * abs(a[i] - x));
    return x % w;
}
void solve() {
    cin >> n; rep(i, 1, n) cin >> a[i];
    cout << min(get(a[1]), get(a[n])) + (a[n] - a[1]) << '\n';
}   
posted @ 2025-08-22 17:42  v1ne0qrs  阅读(9)  评论(0)    收藏  举报