[组合计数] CF1332E Height All the Same

posted on 2024-06-14 12:38:43 | under | source

观察到奇偶性相同的元素一定可以对较小者不断放两个方块,使得它们相等。于是条件可以转化为所有 \(a\) 奇偶性相等。

\(b_{i,j}=0/1\) 表示 \(a_{i,j}\) 偶数还是奇数,将原矩阵视作网格图,那么相邻元素同时 \(+1\) 等价于将这条边的两端的 \(b\) 取反。

然后考虑一条路径 \(p_1\to p_2\dots \to p_m\),那么可以对路径上的边操作,使得恰好只有 \(p_1,p_m\) 取反。假如是让所有 \(b\) 变成 \(0\),那么可以让两个 \(1\) 按照上面方式都变成 \(0\)

全变成 \(1\) 也同理,所以 \(1\)\(0\) 的个数为偶数时合法。

\(c_0,c_1\) 表示 \(b_{i,j}=0/1\) 时,\(a_{i,j}\) 有几种可选方案。可以分类计算答案:

  • \(2\nmid nm\)

\[ans=\sum\limits_{i=0}^{nm} {{nm}\choose i} {c_0}^i{c_1}^{nm-i} \]

  • \(2\mid nm\)

\[ans=\sum\limits_{2\mid i}^{nm} {{nm}\choose i} {c_0}^i{c_1}^{nm-i} \]

看了看数据范围,暴力计算是不可能的。注意到 \(2\nmid nm\) 的情况符合优美的二项式定理,即等价于 \((c_0+c_1)^{nm}\)

但是 \(2\mid nm\) 中只看偶数,怎么办?回想起数学课上学等比数列求和也有类似的题,是加入 \(-1\) 然后和原序列加起来,消掉我们不想要的项。

所以不难想出:

\[ans=\frac {(c_0+c_1)^{nm}+(-c_0+c_1)^{nm}} 2 \]

随便敲个快速幂就好,欧拉定理?感觉没啥必要。

代码

#include<bits/stdc++.h>
using namespace std;

#define int long long
const int mod = 998244353; 
int n, m, l, r, _l, _r, c0, c1;
int ans;

inline int qstp(int a, int k) {int res = 1; for(; k; k >>= 1, a = a * a % mod) if(k & 1) res = res * a % mod; return res;}
signed main(){
	cin >> n >> m >> l >> r;
	_l = (l + 1) / 2 * 2, _r = r / 2 * 2;
	c0 = ((_r - _l) / 2 + 1) % mod;
	c1 = (r - l + 1 - c0) % mod;
	if((n * m) % 2 == 1)
		cout << qstp((c0 + c1) % mod, n * m) % mod;
	else
		cout << (qstp((c0 + c1) % mod, n * m) + qstp((-c0 + c1 + mod) % mod, n * m)) % mod * qstp(2, mod - 2) % mod;
	return 0;
}
posted @ 2026-01-13 11:26  Zwi  阅读(0)  评论(0)    收藏  举报