同余定理与阶乘取模:信息学奥赛 2033 题 O(n) 解法详解与 3 种优化思路
同余定理与阶乘取模信息学奥赛高阶算法精解与实战优化1. 同余定理的竞赛应用精髓在算法竞赛中同余定理绝非简单的数学概念而是解决大数问题的核心工具。当处理阶乘之和这类问题时直接计算数值往往导致溢出而同余运算能完美规避这一风险。关键在于理解基本性质(a b) mod m ((a mod m) (b mod m)) mod m(a × b) mod m ((a mod m) × (b mod m)) mod m实战技巧当模数M1e6时利用同余性质可将10^100级别的计算压缩到int范围内。例如计算1!2!...n! mod M时每步运算都即时取模避免数值爆炸。注意当n ≥ M时n! mod M 0因为M的因子已包含在连乘积中这是重要的剪枝条件2. 阶乘模的四种经典解法对比2.1 暴力解法O(n²)int ans 0; for(int i1; in; i){ int fact 1; for(int j1; ji; j) fact fact * j % M; ans (ans fact) % M; }缺陷n1e6时运算次数达5e11次完全不可行2.2 递推优化O(n)int num 1, sum 0; for(int i1; imin(n,M-1); i){ // 当i≥M时i!%M0 num num * i % M; sum (sum num) % M; }优势利用i! mod M (i × (i-1)! mod M) mod M的性质将每次阶乘计算降为O(1)2.3 预处理阶乘表int fact[M] {1}; // fact[i] i! % M for(int i1; iM; i) fact[i] fact[i-1] * i % M; // 查询时直接取fact[min(n,M-1)]适用场景需要多次查询不同n值时更高效2.4 周期性优化当n远大于M时利用威尔逊定理和周期性若M是素数(M-1)! ≡ -1 mod M对于i ≥ Mi! ≡ 0 mod M3. 性能实测数据对比算法类型n1e3耗时n1e4耗时n1e6耗时适用场景暴力O(n²)2ms200ms1小时仅教学演示递推O(n)0.01ms0.1ms10ms通用最优解预处理O(1)查询5ms初始化5ms初始化5ms初始化多组查询场景周期性优化--0.01msn≫M的特殊情况4. 进阶技巧模数分解与CRT应用当模数M非素数时中国剩余定理(CRT)能分解问题将M分解为互质的p₁^k₁ × p₂^k₂ × ...分别计算ans mod p_i^k_i用CRT合并结果示例代码片段def crt(a_list, m_list): M 1 for m in m_list: M * m result 0 for a, m in zip(a_list, m_list): Mi M // m inv pow(Mi, -1, m) result a * Mi * inv return result % M5. 卡常优化与位运算技巧对于极端数据规模如n1e18还需要快速幂优化计算大指数模数ll qpow(ll a, ll b, ll mod){ ll res 1; while(b){ if(b1) resres*a%mod; aa*a%mod; b1; } return res; }位运算加速用x1代替x*2x1代替x/2内存访问优化用数组代替map存储预处理结果在实际比赛中建议优先实现O(n)递推解法它兼具效率与代码简洁性。当遇到更复杂变式时再考虑组合数学或数论进阶技巧。