Codeforces Round #630 (Div. 2) E. Height All the Same(数学+二项式)

题目:传送门

思路:参考于某大佬(非常清晰+友好)。点此跳转

1. 由于“操作2”,我们可以把原矩阵看作一个01矩阵 (所有数取模2,每个ai,j向上+2 直到最大值和最小值的差<=1)

2. “操作1”的本质是对任意两个点进行翻转(奇偶性变换;考虑如何对不相邻的两个点进行翻转,设这两个点为u、v,那么我们可以对u->v的一条路径上进行相邻两个点的翻转,除了u和v外,路径上其余点均翻转两次)

3.如果所有点奇偶性一致,那么可以通过操作1使得所有点一样高。

4.当n*m是奇数时,那么一定存在着偶数个ai,j 是奇数或者偶数,根据2可知,能将偶数个ai,j 全部翻转使之奇偶性改变(使得所有点奇偶性一致),最后通过操作1能够使所有点一样高。所以当n*m是奇数时,每个点可以取[L,R]的任意值,则 ans=(R-L+1)n*m 

5.当n*m是偶数时,设sum=Σai,j (1<=i<=n,1<=j<=m):

  1)若sum是奇数,则 一定为 奇数个ai,j是奇数 ,奇数个ai,j是偶数 的情况,根据2知  ( 奇数%2 != 0 ),不可能通过 "操作1" 使奇偶性一致。

  2)若sum是偶数,则 一定为 偶数个ai,j是奇数 ,偶数个ai,j是偶数 的情况,由4知,最后能够使所有点一样高。设[ L , R ]中,有x个偶数,y个奇数,我们在n*m个点中选择 i 个点填偶数(偶数有x种),剩下的点填奇数(y种),则 ans=Σ Cin*m * x* yn*m-i ( i = 0,2,4,6,8, ... ,n*m )  。由二项式展开定理可知,ans=(x+y)n*m  * (x-y)n*m / 2  【求展开式中的偶数项 a0 、a2、a4、...】。

###二项式定理

  • formula
 1 #include<bits/stdc++.h>
 2 #pragma GCC optimize(2)
 3 using namespace std;
 4 typedef long long LL;
 5 typedef pair<int,int> pii;
 6 typedef pair<double,double> pdd;
 7 const int N=2e3+5;
 8 const int inf=0x3f3f3f3f;
 9 const LL mod=998244353;
10 const double eps=1e-9;
11 const long double pi=acos(-1.0L);
12 #define ls (i<<1)
13 #define rs (i<<1|1)
14 #define fi first
15 #define se second
16 #define pb push_back
17 #define mk make_pair
18 #define mem(a,b) memset(a,b,sizeof(a))
19 LL read()
20 {
21     LL x=0,t=1;
22     char ch;
23     while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
24     while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
25     return x*t;
26 }
27 LL fp(LL x,LL y)
28 {
29     LL res=1;
30     while(y>0)
31     {
32         if(y&1) res=res*x%mod;
33         x*=x; x%=mod;
34         y>>=1;
35     }
36     return res;
37 }
38 int main()
39 {
40     LL n,m,l,r,ans;
41     scanf("%lld%lld%lld%lld",&n,&m,&l,&r);
42     if(n*m%2==1) ans=fp(r-l+1,n*m);
43     else{
44         LL x,y;//x为[l,r]中偶数的个数,y为奇数;
45         if((r-l)%2==1) x=y=r-l>>1;
46         else if(l&1) x=r-l>>1,y=x+1;
47         else y=r-l>>1,x=y+1;
48         ans=fp(r-l+1,n*m)+fp(x-y,n*m);
49         ans=ans%mod*fp(2LL,mod-2LL)%mod;
50     }
51     printf("%lld
",ans);
52     return 0;
53 }
AC代码
原文地址:https://www.cnblogs.com/DeepJay/p/12728788.html