题:https://codeforces.com/contest/1332/problem/E
题意:给定n*m的矩阵,每个位置都可以叠加高度。有俩种操作,操作1是给相邻位置之间都添加高度1,操作2是给一个位置增加高度2,可进行若干步让所有位置高度相同,问有矩阵有多少种初始状态能达到目的,每个位置的高度取值为[L,R].(只是初始状态用满足高度限制而已)
分析:1、操作1实际上就是互换俩者的奇偶性,操作2实际上就可以让奇偶性相同的位置达到高度相同;
2、所以目的就是通过操作让所有位置的奇偶性相同;
3、假设[L,R]之间偶数个数为x,奇数个数为y。
4、考虑n*m为奇数的情况,那么一定有 i 个偶数高度,(n*m-i)个奇数高度满足要么 i 是偶数,要么(n*m-1)是偶数,通过操作1我们可以把偶数高度和奇数高度的聚在一起,然后通过操作1将偶数个( i 或(n*m-1))的高度转换为另一个奇偶性,这样一来所有位置奇偶性相同。说明在n*m为奇数的情况下,任意位置的初始高度可在[L,R]中任意取值;((x+y)^(n*m))
5、考虑n*m为偶数的情况,只有可能是奇数个偶数高度+奇数个奇数高度 或 偶数个偶数高度+偶数个奇数高度,显然前者没有合法情况只有后者,即=∑(C(n*m,i)*x^i*y^(n*m-i)) (其中 i 为偶数)
根据二项式(a+b)^n=Σ(C(n,i)*a^(n-i)*b^i),而(a-b)^b则在 i 为奇数时 原式的项变为 - 号,俩者相加刚好是答案的2倍。
#include<bits/stdc++.h> using namespace std; #define pb push_back typedef long long ll; const int M=2e5+5; const int mod=998244353; ll ksm(ll a,ll b){ ll t=1; a%=mod; while(b){ if(b&1) t=(t*a)%mod; a=(a*a)%mod; b>>=1; } return t; } int main(){ ios::sync_with_stdio(false); cin.tie(0); ll n,m,L,R; cin>>n>>m>>L>>R; ll x=R/2,y=(R+1)/2; x-=(L-1)/2; y-=L/2; ll ans=ksm(x+y,n*m); if((n*m)%2==0){ ll cha; if(x>y) cha=x-y; else cha=y-x; ans=(ans+ksm(cha,n*m))%mod; ans=(ans*ksm(2,mod-2))%mod; cout<<ans<<' '; } else cout<<ans<<' '; return 0; }