zoukankan      html  css  js  c++  java
  • CF1332E Height All the Same(数学)

    这道题是一道思维+组合计数的题目

    题目给了两个操作,我们发现第一个操作并不改变奇偶,但是可以把相同奇偶的数变成同一个数,第二个数可以改变相邻数的奇偶性

    这样就是一个经典问题了,问每次改变相邻两个数的奇偶性,能不能将所有的数变成奇偶性相同的。

    答案就是,只要在这个区域内,奇数和偶数的个数不都为奇数就行。因为这样我们就可以把个数是奇数的,如果两类都是偶数,随便移一类就行

    通过交换奇偶的方式,全部移到边上靠着

    1 1 1 1

    2 2  2 2

    2 2  2 2 

    例如这样,因为其中一类数都移到边上了,所以剩下的一类数,不但是偶数个,还相邻,这样就可以通过两个两个改变,将所有的数的奇偶性都变成一样。

    这里也就发现如果都是奇数,那是不行的,因为没法配对。

    之后就是一个组合计数问题,如果棋盘是奇数个,那么全部状态都是可以的。如果棋盘是偶数个,我们就可以推出公式,保证在取得时候是偶数个得时候取,因为奇数+奇数=偶数,这种是不行的

    这个公式的物理意义就是在n*m中选i个位置给奇数,那么每个位置有x(l-r中的奇数个数)种选择,其他位置有y种选择(l-r中的偶数个数)

    本题要用快速幂求,还要求逆元,因为根据公式构造得二项式为((x+y)^n*m+(x-y)^n*m)/2;

    因为要取模,所以2要变成逆元

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<map>
    #include<string>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int N=2e5+5;
    const ll mod=998244353;
    ll qpow(ll m,ll k){
        ll res=1%mod;
        ll t=m%mod;
        while(k){
            if(k&1){
                res=res*t%mod;
            }
            t=t*t%mod;
            k>>=1;
        }
        return res%mod;
    }
    
    int main(){
        ll n,m;
        ll l, r;
        ll ans=0;
        cin>>n>>m>>l>>r;
        if(n*m&1){
            ans=qpow(r-l+1,m*n);
            cout<<ans<<endl;
        }
        else{
            ans=qpow(r-l+1,m*n)+((r-l+1)&1?1:0);
            ans%=mod;
            ans=(ans*qpow(2,mod-2));
            ans%=mod;
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    每个Java开发人员都应该知道的4个Spring注解
    JVM中的动态语言支持简介
    深入探索Java设计模式(五)之构建器模式
    Java——MVC模式
    程序出了问题,报错只能参考
    查看电脑端口占用情况
    Java——参数传递
    Python——关于定义过程
    Java——super的使用
    关于如何查看论文是否被SCI或者EI收录
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12696212.html
Copyright © 2011-2022 走看看