题目链接
题目大意
给定n*m的矩阵,每一个a[i][j]代表(i,j)的高度。你可以执行两种操作:
1.给任意一个a[i][j]加上2.
2.给两个相邻的格子都加1.
现在给出n,m,l,r,问你n * m的矩阵,每个格点的初始值是[l,r]中的任意一个,问有多少种初始值,可以使得经过上面的2种操作,所有格点的值相同。
题目思路
1:首先要明白这个矩阵能否最后相同,肯定是只与奇偶性有关。.因为操作1不改变奇偶性,而同奇偶性的数一定可以通过操作1变成相等的数,所以对于一个n∗m的方格,只考虑其奇偶性,问题可以转化为,能否选择两个相邻的方格,使其奇偶性翻转,最后使整个方格奇偶性一致。
2:你会发现如果翻转一奇一偶,矩阵奇数个数和偶数个数还是没变,那么可以改变就是同时翻转奇数或者偶数,则每次奇数变成偶数,或者偶数变成奇数都是2个2个的变化,那么要使其中一个变为0,显然奇数和偶数的个数都是奇数是不行的,否则可行
3:当n*m为奇数时,显然奇数个数和偶数不可能同时为奇数,那么答案就是 ( r − l + 1 ) n m (r-l+1)^{nm} (r−l+1)nm.
4: 当n*m为偶数时,设奇数个数为ji个,偶数个数为ou个。那么答案就是如
∑
i
=
0
n
∗
m
c
(
n
∗
m
,
i
)
j
i
i
∗
o
u
n
m
−
i
\sum_{i=0}^{n*m}c(n*m,i) ji^{i}*ou^{nm-i}
∑i=0n∗mc(n∗m,i)jii∗ounm−i(当i%2==0)
看到这里,其实感觉就容易想到二项式定理了
(
x
+
y
)
n
=
∑
i
=
0
n
∗
x
i
∗
y
n
−
i
(x+y)^{n}=\sum_{i=0}^{n}*x^{i}*y^{n-i}
(x+y)n=∑i=0n∗xi∗yn−i
(
x
−
y
)
n
=
∑
i
=
0
n
∗
x
i
∗
(
−
y
)
n
−
i
(x-y)^{n}=\sum_{i=0}^{n}*x^{i}*(-y)^{n-i}
(x−y)n=∑i=0n∗xi∗(−y)n−i
显然
a
n
s
=
(
(
j
i
+
o
u
)
n
m
+
(
j
i
−
o
u
)
n
m
)
2
ans=\frac{((ji+ou)^{nm}+(ji-ou)^{nm})}2
ans=2((ji+ou)nm+(ji−ou)nm)
代码
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define debug printf("I am here\n");
using namespace std;
typedef long long ll;
const int maxn=2e5+5,mod=998244353;
ll n,m,l,r,ans;
ll qpow(ll a,ll b){
ll ans=1,base=a;
while(b){
if(b&1){
ans=ans*base%mod;
}
base=base*base%mod;
b=b>>1;
}
return ans;
}
signed main(){
scanf("%lld%lld%lld%lld",&n,&m,&l,&r);
if(n*m%2==1){
ans=qpow(r-l+1,n*m);
}else{
ll ji=(r-l+1)/2+(l%2&&(r-l+1)%2);//[l,r]奇数个数
ll ou=r-l+1-ji;//偶数个数
ans=(qpow((ji+ou),n*m)+qpow((ji-ou),n*m))*qpow(2,mod-2)%mod;
}
printf("%lld\n",ans);
return 0;
}
参考链接:https://www.cnblogs.com/qieqiemin/p/12614527.html