2 条题解

  • 1
    @ 2026-10-9 9:00:23

    333

    • 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);
      }
      
      • 1

      信息

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