算法 - 数论 - powmod 快速幂取模

14 篇文章 0 订阅
2 篇文章 0 订阅

理论

  • 定理1: ( a + b ) m o d    c = ( a m o d    c + b m o d    c ) m o d    c (a + b) \mod c = (a \mod c + b \mod c) \mod c (a+b)modc=(amodc+bmodc)modc
    证明:
    a = x c + x 0 , b = y c + y 0 a = xc + x_0, b = yc + y_0 a=xc+x0,b=yc+y0
    ( a + b ) ÷ c = ( x c + x 0 + y c + y 0 ) ÷ c (a + b) \div c = (xc + x_0 + yc + y_0) \div c (a+b)÷c=(xc+x0+yc+y0)÷c
    其中 x c ÷ c = x . . . 0 xc \div c = x ... 0 xc÷c=x...0
    y c ÷ c = y . . . 0 yc \div c = y ... 0 yc÷c=y...0
    显然有 ( a + b ) m o d    c = ( x c + x 0 + y c + y 0 ) m o d    c = ( x 0 + y 0 ) m o d    c (a + b) \mod c = (xc + x_0 + yc + y_0) \mod c = (x_0 + y_0) \mod c (a+b)modc=(xc+x0+yc+y0)modc=(x0+y0)modc
    即: ( a + b ) m o d    c = ( a m o d    c + b m o d    c ) m o d    c (a + b) \mod c = (a \mod c + b \mod c) \mod c (a+b)modc=(amodc+bmodc)modc

  • 定理2: ( a × b ) m o d    c = ( ( a m o d    c ) × ( b m o d    c ) ) m o d    c (a \times b) \mod c = ((a \mod c) \times (b \mod c)) \mod c (a×b)modc=((amodc)×(bmodc))modc
    证明:
    a = x c + x 0 , b = y c + y 0 a = xc + x_0, b = yc + y_0 a=xc+x0,b=yc+y0

    ( a × b ) m o d    c = ( ( x c + x 0 ) × ( y c + y 0 ) ) m o d    c = ( x y c 2 + x 0 y 0 + x 0 y c + y 0 x c ) m o d    c = ( x 0 y 0 ) m o d    c = ( ( a m o d    c ) × ( b m o d    c ) ) m o d    c (a \times b) \mod c = ((xc + x_0) \times (yc + y_0)) \mod c = (xyc^2 + x_0 y_0 + x_0 y c + y_0 x c) \mod c = (x_0 y_0 ) \mod c = ((a \mod c) \times (b \mod c)) \mod c (a×b)modc=((xc+x0)×(yc+y0))modc=(xyc2+x0y0+x0yc+y0xc)modc=(x0y0)modc=((amodc)×(bmodc))modc

  • 推理1: x N 0 m o d    c = ( ( m x m o d    c ) × ( x N 1 m o d    c ) 2 ) m o d    c ; N 0 = m + 2 × N 1 x^{N_0} \mod c =((mx \mod c) \times (x^{N_1} \mod c)^2) \mod c; N_0 =m + 2 \times N_1 xN0modc=((mxmodc)×(xN1modc)2)modc;N0=m+2×N1

实现

  • 递归
#include <cinttypes>

uintmax_t pow_mod(const uintmax_t x,const uintmax_t n, const uintmax_t c = INT_MAX)
{
    if (n == 0) return 1;
    if (n == 1) return x%c;
    if (n == 2) return ((x%c) * (x%c)) % c;
    const auto y = pow_mod(x, n >> 1,c) % c;
    if (n % 2) return ((x % c) * ((y * y) % c)) % c;
    return (y * y) % c;
}

  • 循环
#include <cinttypes>

uintmax_t pow_mod(const uintmax_t x,const uintmax_t n, const uintmax_t c = INT_MAX)
{
    uintmax_t res = 1;
    uintmax_t y = x;
    for (uintmax_t i = n; i != 0;i >>= 1) {
        if (i & 1) res = (res * y) % c;
        y = (y * y) % c;
    }
    return res;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tadus_zeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值