CodeForces 1332E Height All the Same
题意
对于一个n∗m的矩阵,有两种操作
- 一个格子加二
- 一个格子和另一个相邻的格子同时加一
通过这两种操作最终使得所有矩阵元素相等
对于矩阵元素来说,有L≤ai,j≤R(1≤i≤n,1≤j≤m)
问有多少种方案数,答案\mod 998244353
分析
由于最终相等的值与答案无关,所以我们不妨所有元素减去L,即所有元素的值在[0,R-L]区间内
而所有元素通过操作可以相差最多为1(仅仅分奇偶)
这种操作可以不断进行,所以我们只需看数字的奇偶性
为描述,我们不妨将所有元素视为0,1
对于1来说,其周围一定没有1,否则可以填上使两元素变为0,那么如果该1和旁边的0同时加1,我们可以发现0和1互换位置了
这种操作的意义在于,对于任意的一个1,我们可以通过操作使其变到其他任意的位置
那么如果矩阵中有奇数个1,我们可以将其变为1个1,而偶数个1,我们一定可以将两个1进行配对,从而消去
我们思考n*m的奇偶性
- 若n*m为奇数,若有偶数个1,则满足条件,若有奇数个1,我们将其变为1个1,并将其移动到边角上,通过蛇形配对,我们可以将除该元素的其他元素同时加上1,所有元素相等,因此所有取值皆满足答案就是(R-L+1)^{n*m}(每个数有R-L+1中取法)
- 若n*m为偶数,若有偶数个1,则满足条件,若有奇数个1,我们可以发现元素和为奇数,而n*m为偶数,元素和无论怎么增加(每次加二),一定是奇数,无法整除n*m一定不满足,因此答案为偶数个1的取值方式
接下来分析n*m为偶数时,有多少种偶数个1的取值方式:
如果R-L+1为奇数,则可以取\frac {R-L+2} {2}种奇数,否则为\frac {R-L+1} {2}种奇数,设为j,设R-L+1为t
答案为C^0_{n*m}*j^0*(t-j)^{n*m}+C^2_{n*m}*j^2*(t-j)^{n*m-2}+\cdots+C^{n*m}_{n*m}*j^{n*m}*(t-j)^{0},意思为挑偶数(2*k)个奇数(C^{2*k}_{n*m}),每个奇数有j中取值,其余偶数有t-j种取值
发现这个式子是二项展开式的偶数项,那么可以推导下(半小时无从下手,我对不起高中数学老师)
(j+(t-j))^{n*m}=C^{0}_{n*m}j^{0}(t-j)^{n*m}+C^{1}_{n*m}j^{1}(t-j)^{n*m-1}+\cdots+C^{n*m}_{n*m}j^{n*m}(t-j)^{0}
(j-(t-j))^{n*m}=C^{0}_{n*m}j^{0}(t-j)^{n*m}-C^{1}_{n*m}j^{1}(t-j)^{n*m-1}+\cdots+C^{n*m}_{n*m}j^{n*m}(t-j)^{0}
第二个式子偶数项是加号,奇数项是减号(从0开始计数)
两式相加除以二即为偶数项和,即
\frac{(j+(t-j))^{n*m}+(j-(t-j))^{n*m}}{2}
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>
#define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define ls st<<1
#define rs st<<1|1
#define pii pair<int,int>
#define rep(z, x, y) for(int z=x;z<=y;++z)
#define com bool operator<(const node &b)
using namespace std;
const int maxn = (ll) 3e5 + 5;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
int qp(int x, int y) {
int ans = 1;
while (y) {
if (y & 1)
ans = ans * x % mod;
x = x * x % mod;
y >>= 1;
}
return ans;
}
signed main() {
start;
int n, m, L, R;
cin >> n >> m >> L >> R;
int t = R - L + 1;
if ((n * m) & 1) {
cout << qp(t, n * m) % mod;
} else {
int j;
if (t & 1)
j = (t + 1) / 2;
else
j = t / 2;
int ans = ((qp(t, m * n) + qp((2 * j - t), m * n)) % mod + mod) % mod * qp(2, mod - 2) % mod;
cout << ans;
}
return 0;
}
标签:
数论
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法