核心概述

模运算(Modular Arithmetic):在给定正模 m 下进行加减乘规约、规范化与常见组合操作的通用模板;处理负数规约、溢出安全乘法、幂与逆等常见细节。

原文引述

Description: Utilities for modular arithmetic: normalize to [0,m), constant-time add/sub with wrap-around, safe multiply (u128/Barrett/Montgomery), and ModInt wrapper integrating pow/inv. Time: O(1) per op (amortized) Status: tested

  • 函数/接口(据常见实现)

    • normMod(a, m) → 将任意整数 a 规范到 [0, m)。
    • addMod(a, b, m) / subMod(a, b, m) → 返回 (a±b) mod m,常用“若超界加/减 m”的分支避免取模。
    • mulMod(a, b, m) → (a·b) mod m(64 位用 __int128 或参见 090-数论-长整型模乘)。
    • powmod(a, e, m) → a^e mod m(见 091-数论-模幂)。
    • inv(a, m) → a^{-1} mod m(若 gcd(a,m)=1,见 088-数论-模逆)。
    • 结构体 ModInt 或 runtime Mod:
      • 字段 v ∈ [0, MOD);重载 +,-,*,/,+=, …;/ 调用 inv。
      • 支持快速幂、读写与与整型互转;可提供 getMod/setMod(运行时模)。
  • 规范化与边界

    • 负数规约:((a % m) + m) % m 保证落在 [0, m)。
    • m==1 的约定:所有结果为 0(避免除以 0 的操作)。
    • 加减包裹:
      • add: x += y; if (x >= m) x -= m
      • sub: x -= y; if (x < 0) x += m
    • 乘法溢出:优先 __int128;若不可用,采用 Barrett/Montgomery(见 090-数论-长整型模乘)。
  • 组合套路

  • 实现要点

    • 统一类型与取模次数:尽量减少重复 % 操作,先规范再复用。
    • 对性能敏感路径,使用分支而非 % 降常数;乘法采用安全乘。
    • ModInt 需注意:
      • 常量 MOD 为编译期常量时便于优化;运行时模需小心全局状态。
      • 除法仅在可逆时定义;调试模式可断言 gcd(v, MOD)==1。
      • 与内置整型的隐式转换要谨慎,避免精度与符号陷阱。
  • 输出语义

    • 所有结果规范到 [0, m);ModInt 封装保证不变式成立。
  • 复杂度

    • 基本加减 O(1);乘法 O(1)(取决于后端);幂/逆参见对应模板。
  • 使用与注意

    • 溢出与 UB:所有中间运算用无符号与 128 位/降余法实现。
    • 选择后端:
      • 少量运算:__int128 最简洁;
      • 批量固定奇模:Montgomery 较优;
      • 跨模或平台限制:Barrett 降余更通用。
    • 与随机大数判素/分解等算法同用时,务必采用安全模乘。

关联节点