当前位置: 首页 > news >正文

题解:Luogu P10644 [NordicOI 2022] 能源网格 Power Grid

题意

给定 \(n,m\)。对于 \(n\times m\) 的网格 \(a\),定义

\[c_{i,j}=\left\lvert \sum_{k=1}^{n}a_{k,j}-\sum_{k=1}^{m}a_{i,k} \right\rvert \]

现在给定 \(c\),构造一组合法的 \(a\)。数据保证有解。\(1\leq n,m\leq 10^3\)\(0\leq c_{i,j}\leq 10^3\)

题解

NOIP 模拟赛 T4,很好的构造题。

\(X_{i}=\sum\limits_{j=1}^ma_{i,j}\)\(Y_j=\sum\limits_{i=1}^na_{i,j}\),那么 \(c_{i,j}=\lvert X_i-Y_j\rvert\)

我们考虑先确定 \(X,Y\),再通过 \(X,Y\) 推出 \(a\)。如果我们构造出一组 \(X,Y\) 使得 \(\sum X=\sum Y\),那就可以构造出一组合法的 \(a\)。具体来说:

  • 对于每个 \(1\leq i<n\),令 \(a_{i,m}\leftarrow X_i\)
  • 对于每个 \(1\leq j<m\),令 \(a_{n,j}\leftarrow Y_j\)
  • \(a_{n,m}\leftarrow X_n+Y_m-\sum X\)
  • 对于每个 \(1\leq i<n,1\leq j<m\),令 \(a_{i,j}\leftarrow 0\)

不难发现这样构造后,每个 \(1\leq i<n\) 对应的行和都是 \(X_i\),每个 \(1\leq j<m\) 对应的列和都是 \(Y_j\)。同时可以计算出第 \(n\) 行的和为

\[\left(\sum_{j=1}^{m-1}Y_j\right)+X_n+Y_m-\left(\sum\limits_{i=1}^{n}X_i\right)=X_n \]

\(m\) 列的和可以同理算出是 \(Y_m\)

接下来考虑如何构造一组 \(X,Y\)。考察一个位置 \(u,v\) 使得 \(c_{u,v}\) 取到最大值,那么 \(c_{u,v}\) 要么是 \(\left\lvert \max\limits_{i=1}^n X_i-\min\limits_{i=1}^mY_i \right\rvert\),要么是 \(\left\lvert \max\limits_{i=1}^m Y_i-\min\limits_{i=1}^nX_i \right\rvert\),不妨钦定其为前者,并且钦定 \(X_u=c_{u,v},Y_v=0\)

此时所有的 \(Y\) 必定非负,因此对于每个 \(j\neq v\),我们可以根据 \(c_{u,j}=|X_u-Y_j|\) 确定 \(Y_j=X_u-c_{u,j}\)

接下来对于每个 \(i\neq u\),考察 \(X_i\) 的取值。首先根据 \(c_{i,v}=|X_i-Y_v|=|X_i|\) 可以得出 \(X_i=\pm c_{i,v}\),也就是说 \(X_i\) 至多有 \(2\) 种取值。再根据其他的 \(c_{i,j}\) 可以推出更多关于 \(X_i\) 的限制,最终每个 \(X_i\) 必然是没有合法取值/恰有 \(1\) 种取值/有 \(2\) 种取值的形式。若存在 \(X_i\) 没有合法取值则当前 case 无解。而对于 \(2\) 种取值的 \(X_i\),我们需要引入更多的条件对其加以限制。

考虑我们还漏了什么限制条件。注意到一开始我们钦定了 \(Y_v=0\),然而事实上 \(Y_v\) 可以等于其它非 \(0\) 的数,此时我们需要调整。由于我们需要让所有的 \(X,Y\) 依然满足 \(c\) 的限制,所以只能考虑给 \(X,Y\) 全体加减一个常数 \(k\)。给 \(X,Y\) 全体 \(+k\) 会使得 \(\sum X-\sum Y\) 增加 \(k(n-m)\),我们最终有解的充要条件\(\sum X-\sum Y=0\),因此在钦定 \(Y_v=0\),我们还需要保证得到的 \(\sum X-\sum Y\equiv 0\pmod{|n-m|}\)

那么如何找出一组 \(X\) 满足这个条件呢?考虑背包。对于每个有 \(2\) 种合法取值 \(p,q\)\(X_i\),钦定 \(p\leq q\),我们先令 \(X_i\leftarrow p\),然后将其作为一个体积为 \(q-p\) 的物品扔进背包中。现在所有的 \(X,Y\) 都有了具体值(注意我们只是给 \(X\) 暂定了一个值,不保证合法),然后我们用背包找出这些物品能拼凑出的所有可能的体积总和,找到一个可能的体积总和 \(S\) 满足 \(S\equiv \sum X-\sum Y\pmod{|n-m|}\),然后根据这个 \(S\) 反推回去确定每个 \(X\) 的实际取值。具体来说,用 \(f_{i,j}\) 表示考虑前 \(i\) 个物品,能否选出若干个使得体积总和为 \(j\),转移不再赘述。反推时,设考虑到第 \(i\) 个物品对应的 \(X_k\),若 \(f_{i-1,S}=0\)\(X_k\) 的取值需要更改为当前物品的体积 \(q\),然后令 \(S\leftarrow S-q\) 即可。

注意到值域是 \(\mathcal{O}(nV)\) 量级的,需要用 bitset 把背包优化到 \(\mathcal{O}\left(\dfrac{n^2V}{\omega}\right)\)

这样我们就确定了 \(X,Y\) 的取值,调整后用前文中的方法构造 \(a\) 即可。

对于 \(c_{u,v}\) 的另一种 case,把 \(a\) 转置之后再做一遍即可。

时间复杂度为 \(\mathcal{O}\left(\dfrac{n^2V}{\omega}+nV+nm\right)\)

代码

inline bool check() {int sum = 0;for (int i = 1; i <= m; ++i) sum -= y[i] = c[mxx][mxy] - c[mxx][i];szp = 0;for (int i = 1; i <= n; ++i) {int nx = -c[i][mxy], sx = c[i][mxy];bool suc1 = 1, suc2 = 1;for (int j = 1; j <= m; ++j) {int x1 = y[j] - c[i][j], x2 = y[j] + c[i][j];suc1 &= x1 == nx || x2 == nx;suc2 &= x1 == sx || x2 == sx;}if (!suc1 && !suc2) return 0;if (suc1 && suc2) x[i] = nx, p[++szp] = {i, sx - nx};else x[i] = suc1 ? nx : sx;sum += x[i];}f[0].reset(), f[0][0] = 1;for (int i = 1; i <= szp; ++i) f[i] = f[i - 1] | (f[i - 1] << p[i].second);int s = -1, d = abs(n - m);if (!d) s = -sum;else for (int i = (d - sum % d) % d; i < V; i += d) if (f[szp][i]) { s = i; break; }if (s < 0) return 0;for (int i = szp; i; --i) if (!f[i - 1][s]) x[p[i].first] += p[i].second, s -= p[i].second;if (d) {int sumx = 0, sumy = 0;for (int i = 1; i <= n; ++i) sumx += x[i];for (int i = 1; i <= m; ++i) sumy += y[i];int t = (sumy - sumx) / (n - m);for (int i = 1; i <= n; ++i) x[i] += t;for (int i = 1; i <= m; ++i) y[i] += t;}for (int i = 1; i <= n; ++i) fill(a[i] + 1, a[i] + m + 1, 0);for (int i = 1; i < n; ++i) a[i][m] = x[i];for (int i = 1; i < m; ++i) a[n][i] = y[i];a[n][m] = x[n];for (int i = 1; i < m; ++i) a[n][m] -= y[i];return 1;
}
http://www.hskmm.com/?act=detail&tid=35340

相关文章:

  • 题解:Luogu P10004 [集训队互测 2023] Permutation Counting 2
  • 题解:Luogu P2075 区间 LIS
  • 英语_阅读_2050 Space tourism_待读
  • goframe框架命令行工具gf在zsh下不能用
  • 题解:Luogu P4143 采集矿石
  • 从18w到1600w播放量,我的一点思考。
  • 扣一个细节问题
  • 10.20java作业
  • 题解:Luogu P14175 【MX-X23-T5】向死存魏
  • 题解:Luogu P14254 分割(divide)
  • 题解:Luogu P6898 [ICPC 2014 WF] Metal Processing Plant
  • 20251020
  • 32-腾讯IM接入资料和定价
  • 题解:AtCoder ARC207A Affinity for Artifacts
  • 构造单
  • [笔记]高斯消元
  • 半导体设备各细分领域的国内外龙头公司
  • CSP-S 34
  • 02.Python百行代码实现抽奖系统
  • CSP-S 35
  • CSP-S 29
  • 2025网络安全振兴杯wp
  • 10.20每日总结
  • CSP-S 31
  • 后缀树
  • ES原理、zookeeper、kafka
  • CF1606E Arena 题解(动态规划)
  • 服务器CPU市场概况2025
  • CSP-S 24
  • 读书笔记:深入理解java虚拟机