Codeforces 1332E Height All the Same [ 紫 ] [ 组合数学 ] [ 二项式定理 ]

Height All the Same:小清新二项式定理题。话说这玩意真的有紫吗,不管是推式子部分还是观察部分都比较显然吧,感觉可以蓝。

转化

首先看到每次进行 1,2 的增加,不难联想到奇数和偶数的性质。我们以 2 为粒度变化,操作 1 就相当于给网格中相邻两个格子的奇偶性发生改变,而操作 2 是在所有的格子奇偶性相同的时候把网格图的所有数字变得相等的。所以本题中只有操作 1 的改变相邻两个格子的奇偶性的操作是有用的,并且我们可以由此转化为网格上的 0,1 问题(按照奇偶性)。

观察

那么操作 1 有啥性质呢?不难发现,假设相邻的两个有一个 0 和一个 1,那么我们执行操作,就相当于把这个 1 进行了一次上下左右的移动,0 也是同理的。而如果操作的两个数奇偶性相同,那么执行操作后奇偶性还是相同,就相当于没有用。

也就是说,我们要消除 1,让它全变 0;或者要消除 0,让它全变 1

消除该如何做呢?显然是将两个本来不挨在一起的两个 01 通过操作 1 挨在一起,然后再对这个两个数执行一次操作 1,就能起到消除这两个 01 的效果。因为是两两相消的,所以要消除的数字必须出现偶数次。

但到底要消除 0 还是消除 1 呢?这个我们就要分讨了。

n×m 为奇数时

显然填什么数都合法,因为奇数要拆分成奇数和偶数,而 01 的个数在 n×m 为奇数的情况下不可能同奇偶性,必然存在 01 满足个数为偶数的要求,所以所有状态都合法,答案为 (rl+1)n×m

n×m 为偶数时

这时候就不是填啥都合法了,因为 0,1 的个数同奇偶性,所以 0,1 的个数都必须是偶数才能两两消除完。

假设 [l,r] 中的奇数个数为 odd,偶数个数为 even

那么这时候的答案是 imod2=0Cn×mi×oddi×evenn×mi。暴力计算显然会超时。

观察到式子只对偶数项求和,并且还有组合数,很容易想到用二项式来加速计算。所以我们考虑对所有项求和,然后把奇数项乘一个 1,最后将结果再加上所有项的和,就是偶数项的两倍了。因为奇数项全部被抵消了。

这个结果式子就是 i=0n×mCn×mi×oddi×evenn×mi×(1)i+i=0n×mCn×mi×oddi×evenn×mi2

那么我们现在就可以用二项式定理来化简了,最后的结果是:

i=0n×mCn×mi×(odd)i×evenn×mi×+i=0n×mCn×mi×oddi×evenn×mi2

=(odd+even)n×m+(odd+even)n×m2

快速幂计算即可,时间复杂度 O(logn×m)

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
#define lc(x) (tr[x].ls)
#define rc(x) (tr[x].rs)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
const ll mod=998244353;
ll n,m,l,r;
ll qpow(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1)res=(res*a)%mod;
        b>>=1;
        a=(a*a)%mod;
    }
    return res;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m>>l>>r;
    ll odd=(r+1)/2-(l-1+1)/2,even=r/2-(l-1)/2;
    if((1ll*n*m)&1)cout<<qpow(r-l+1,1ll*n*m);
    else cout<<(qpow(even-odd,1ll*n*m)+qpow(even+odd,1ll*n*m))%mod*qpow(2,mod-2)%mod;
    return 0;
}
posted @   KS_Fszha  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示