模运算的相关扩展

详细见模逆元 - OI Wiki 

模逆元

概念

非零实数 𝑎 ∈𝐑 的乘法逆元就是它的倒数 𝑎−1。类似地,数论中也可以定义一个整数 𝑎 在模 𝑚 意义下的逆元 𝑎−1mod𝑚,或简单地记作 𝑎−1。这就是 模逆元(modular multiplicative inverse),也称作 数论倒数

注意:在模运算下无法直接进行除法操作!!!!!,需要用「乘法逆元」替代除法实现除数操作

求解方法

快速幂法

这一方法主要适用于模数是素数 𝑝 的情形。此时,由 费马小定理求得

image

//快速幂(取余新增变量mod)
int binpow(int a, int b){
    if(b == 0) return 1;
    int res = 1;
    while(b){
        if(b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

//逆元
binpow(a, mod - 2);

 

例题C-子段乘积_牛客2025秋季算法编程训练联赛4-基础组

题目要求要对答案取模操作,这是模运算,不能直接使用除法运算,那么这时可以考虑逆元代替除法,通过尺取法+逆元操作,将时间复杂度压缩到nlogm

查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;

//快速幂(取余新增变量mod)
int binpow(int a, int b){
    if(b == 0) return 1;
    int res = 1;
    while(b){
        if(b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

//求最大公约数
int gcd(int a, int b){
    return b ? gcd(b, a % b) : a;
}

void solve(){
    int n, k;
    cin >> n >> k;
    vector<int> a(n + 1);
    for(int i = 1; i <= n; ++i) cin >> a[i];
    int maxn = 0;
    int r = 1, l = 1;
    int sum = 1;
    while(r <= n){
        if(a[r]){
            sum = sum * a[r] % mod;
            if(r - l + 1 == k){
                if(sum > maxn) maxn = sum;
                sum = sum * binpow(a[l], mod - 2) % mod;
                l++;
            }
        }else{
            l = r + 1;
            sum = 1;
        }
        r++;
    }
    cout << maxn << endl;
    return ;
}

signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    int T = 1;
    //cin >> T;
    while(T--){
        solve();
    }
    return 0;
}

 

posted @ 2025-11-07 00:55  菜鸡の编程日常  阅读(15)  评论(0)    收藏  举报