Codeforces 1332E Height All the Same
Description
给定 $n,m,L,R$,求大小为 $n\times m$ 的矩阵 $a_{i,j}$ 中满足 $L\le a_{i,j}\le R$ 并且可以通过相邻元素一起 $+1$、元素 $+2$ 两种操作使整个矩阵相等的数量 $\bmod ~998244353$。
Solution
首先,可以观察到结果和实际的高度无关,之和高度的奇偶性有关。
这个很好理解,因为我们可以用操作 2 使得在同奇偶性的数域内变化。
现在只考虑操作 1。
我们用 $E$ 表示 $[L,R]$ 中的偶数个数,$O$ 表示 $[L,R]$ 中的奇数个数。
接下来要分两种情况。
如果 $n \cdot m$ 是奇数的话,可以证明,任何一种方式都是合法的。
为什么?因为这以为着图中要么有偶数个 $a \in \text{Even}$,要么有偶数个 $a \in \text{Odd}$,无论是哪种,我们都可以用操作 1 使得这部分变成与它相反的奇偶性,那么奇偶性都相等,答案也就相等了。
所以这时有答案为:
$$ \prod_{i = 1}^{n} \prod_{j = 1}^{m}(R-L+1) = (R-L+1)^{nm}$$
否则就是 $n \cdot m$ 是偶数。
设最终是 $h$ 层,那么最终 $\sum_{i=1}^{n}\sum_{j=1}^{m} a_{i, j} = nmh$,显然是个偶数。这时我们把过程倒过来想,无论怎么操作,$\sum_{i=1}^{n}\sum_{j=1}^{m} a_{i, j}$ 始终是偶数,所以我们只要保持局面的和是偶数,就一定有解。
可能你又想问为什么这个是充要条件,因为和是偶数,说明一定有偶数个 $a \in \text{Odd}$,所以类比上面就可知了。
但是这个怎么求呢?
显然,我们只要保持局面上 $a \in \text{Odd}$ 的个数为偶数就行了。不妨设有 $2i$ 个位置是奇数,$[L,R]$ 中有 $O$ 个奇数,$E$ 个偶数。
答案为:
$$ \sum_{i = 0}^{\frac{nm}{2}}\left(\begin{matrix} nm \\ 2i \end{matrix} \right )O^{2i} E^{nm - 2i} $$
可是这个式子怎么求呢?
这让我们想到二项式定理。
二项式定理的表述为:
$$ (x+y)^{z} = \sum_{i=0}^{z}\left(\begin{matrix} z \\i \end{matrix}\right)x^i y^{z-i} $$
是不是比较相似呢?
$$ (O + E)^{nm} = \sum_{i = 0}^{nm} \left(\begin{matrix} nm \\ i \end{matrix} \right) O^i E^{nm - i}$$
然后偶数项和奇数项分别拉出来。
$$(O+E)^{nm} = \sum_{i = 0}^{\frac{nm}{2}} \left(\begin{matrix} nm \\ 2i \end{matrix} \right ) O^{2i} E^{nm - 2i} + \sum_{i = 1}^{\frac{nm}{2}} \left(\begin{matrix} nm \\ 2i-1 \end{matrix} \right ) O^{2i-1} E^{nm - (2i-1)}$$
发现左半边就是我们想要的东西。
怎么消掉右半边?发现:
$$ (O-E)^{nm} = \sum_{i = 0}^{\frac{nm}{2}} \left(\begin{matrix} nm \\ 2i \end{matrix} \right ) O^{2i} E^{nm - 2i} - \sum_{i = 1}^{\frac{nm}{2}} \left(\begin{matrix} nm \\ 2i-1 \end{matrix} \right ) O^{2i-1} E^{nm - (2i-1)} $$
两式相加,得到:
$$ (O + E)^{nm} + (O - E)^{nm} = 2 \sum_{i = 0}^{\frac{nm}{2}} \left(\begin{matrix} nm \\ 2i \end{matrix} \right ) O^{2i} E^{nm - 2i}$$
所以,答案就是:
$$ \frac{(O + E)^{nm} + (O - E)^{nm}}{2} $$
使用快速幂可以做到 $\mathcal O(\log (nm))$,值得注意的是使用欧拉定理应当特判底数等于 $0$ 的情况,否则会被极端数据卡掉,例如:
998244352 2 1 998244353
答案是 $499122177$。
具体细节看代码吧。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const LL MOD = 998244353; LL qpow(LL a, LL p) { if(a == 0) return 0; LL res = 1; while(p) { if(p & 1) res = res * a % MOD; a = a * a % MOD; p >>= 1; } return res; } int main() { LL n, m, l, r; cin >> n >> m >> l >> r; if(n * m & 1) cout << qpow((r - l + 1) % MOD, n * m % (MOD - 1)) << endl; else { LL E = (r >> 1) - (l - 1 >> 1); LL O = r - l + 1 - E; cout << ((qpow((O + E) % MOD, n * m % (MOD - 1)) + qpow((O - E + MOD) % MOD, n * m % (MOD - 1))) * 499122177 % MOD) << endl; // 499122177 是 mod 998244353 意义下 2 的逆元 } return 0; }