1 条题解

  • 0
    @ 2026-4-29 16:53:59

    核心结论(一句话)

    1. 能无限减 → 输出 -1
    2. 最多只能减 1 → 输出总和 -1
    3. 完全不能减 → 输出原总和

    代码只做三件事

    • 检查原数组是否稳定(good()
    • 把最小值减 1,再检查是否稳定
    • 都不稳定 → 无限减(-1)

    1. 题目核心机制(关键观察)

    每次操作选 k 个元素,能真正减少总和的充要条件:

    $$\exists\ i < n,\ \exists\ a_j, a_k \text{ 满足 } \ \ a_j \not\equiv a_k \pmod i $$

    或者: 数组总和不能被 n 整除


    2. 最终稳定态定义(good 函数)

    数组再也无法减少的充要条件:

    $$\forall\ 2 \le i \le n-1,\quad \forall\ j:\ \ a_j \equiv a_0 \pmod i $$

    并且:

    i=1nai    0(modn)\sum_{i=1}^n a_i \ \ \equiv \ \ 0 \pmod n

    重要推论

    • n > 23 时,满足所有同余条件 → 所有数必须完全相等
    • n ≤ 23 时,只需检查模 2~n-1 全部同余

    3. 完整判定逻辑(官方解法)

    1. 若原数组已经是稳定态 → 答案 = 总和
    2. 否则,把最小值减 1,再检查
       若此时稳定 → 答案 = 总和 - 1
    3. 否则 → 可以无限减 → 输出 -1
    

    4. 标程代码逐行详解

    (1)good() 函数:判断数组是否稳定

    bool good() {
        bool ok = 1;
        if (n > 23) {
            // n>23 时,必须全部相等才能稳定
            for (int i=0;i<n;i++) {
                if (a[i] != a[0]) ok = 0;
            }
        } else {
            // n<=23 时,检查所有 2<=i<=n-1 同余
            for (int i=2;i<n;i++) {
                for (int j=0;j<n;j++) {
                    if (a[j]%i != a[0]%i) {
                        ok = 0; break;
                    }
                }
            }
        }
        // 总和必须被 n 整除
        ok &= (s % n == 0);
        return ok;
    }
    

    (2)主逻辑

    sort(a.begin(), a.end());
    
    if (good()) {
        cout << s << "\n";
        continue;
    }
    
    // 尝试把最小值减 1
    a[0]--; s--;
    
    if (good()) {
        cout << s << "\n";
        continue;
    }
    
    // 都不行 → 无限减
    cout << -1 << "\n";
    

    5. 为什么 n > 23 直接判全相等?

    因为:

    LCM(1,2,...,23)>109\text{LCM}(1,2,...,23) > 10^9

    而题目中 ai109a_i \le 10^9。 → 满足所有同余条件 等价于所有数相等


    6. 样例解释

    样例 1

    2
    2 1
    
    • 原数组不稳定
    • 减 1 → [1,1] 稳定
    • 输出:2

    样例 2

    4
    3 3 3 3
    
    • 全相等,总和被 4 整除
    • 输出:12

    样例 3

    8
    1 2 ... 8
    
    • 原数组不稳定
    • 减 1 后仍不稳定
    • 输出:-1

    7. 时间复杂度

    O(n23)O(n)O(n \cdot 23) \approx O(n)

    完美通过 n106n \le 10^6


    8. 最简记忆口诀(背这个就够)

    1. n>23:必须全相等才不能减
    2. n≤23:所有数模 2~n-1 都同余
    3. 总和必须被 n 整除
    4. 能减就减 最多 1
    5. 否则 -1

    • 1

    信息

    ID
    6709
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    0
    已通过
    0
    上传者