2 条题解

  • 1
    @ 2026-7-4 9:10:44

    取模的性质: amod  p+bmod  p=(a+b)mod  pa \mod{p} + b \mod{p} = (a + b) \mod{p}

    ∵\because 每个节点 能量被 k>1k \gt 1 整除

    即 最后总能量 能量被 k>1k \gt 1 整除

    又 ∵\because 能量传输不改变总能量

    ∴\therefore 总能量 能量被 k>1k \gt 1 整除

    设 总能量(即 11 的个数)为 cntcnt

    首先,要使操作次数最小

    先要将 cntcnt 个 11 分成 m=cnt/km = cnt / k 组

    再处理每组,

    ∵\because 所有点到中位数的距离和一定最小

    ∴\therefore 将每组的 11 移动到该组的中位数位置

    综上所述,最优策略是,将 cntcnt 个 11 分成 m=cnt/km = cnt / k 组,将每组的 11 移动到该组的中位数位置, 其中 k>1k \gt 1 且 kk 为 cntcnt 的约数。

    怎么计算每组数字到中位数的距离呢?

    用前缀和计算即可

    代码

    辅助数组

    if (a[i]) {
        pos[++cnt] = i;
        sum[cnt] = sum[cnt - 1] + pos[cnt];
    }
    

    其他代码

    for (k = 2; k <= cnt; k++) {
        if (cnt % k != 0) continue;
        int m = cnt / k;
        LL res = 0;
        for (int i = 1; i <= m; i++) {
            int l = (i - 1) * k + 1;
            int r = i * k;
            int mid = l + k / 2;
            // [l, mid]
            int dis_l = mid - l;
            LL ans_l = sum[mid] - sum[l - 1];
            res += pos[mid] * dis_l - ans_l;
            // [mid + 1, r]
            int dis_r = r - (mid + 1);
            LL ans_r = sum[r] - sum[mid + 1 - 1];
            res += ans_r - pos[mid] * dis_r;
        }
        ans = min(ans, res);
    }
    

    信息

    ID
    2656
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    29
    已通过
    6
    上传者