取模运算的性质?

$$(a \times b) \% p = \left[(a \% p) \times (b \% p)\right] \% p$$
证明:
设:$a=k_1p+q_1 , b=k_2p+q_2$
$(a\times b)=(......)\times p+q_1 q_2$
$(a\times b)\%p=(q_1 q_2)\%p$
$a\%p=q_1,b\%p=q_2$

考虑手算$3^{10}$怎么实现?

$3^{10} = (3^2)^5=9^5=9\times 9^4=9\times(81)^2=9\times (81^2)^1$

代码实现

python版本

def func(a, b, k):
    ans = 1
    a %= k
    while b:
        if b % 2 == 1:
            ans = (ans * a) % k
            a = (a * a) % k
            b //= 2
        else:
            a = (a * a) % k
            b //= 2
    return ans


c, d = map(int, input().split())
res = func(c, d, 7)
print(res)

然后可以进行一些优化。比如if和else里面有重合的语句。判断b是否为奇数。还有b整除2可以用位运算提高速度。

def func(a, b, k):
    ans = 1
    a %= k
    while b:
        if b & 1:
            ans = (ans * a) % k
        a = (a * a) % k
        b >>= 1
    return ans


c, d = map(int, input().split())
res = func(c, d, 7)
print(res)

if和else里面重合的语句我们可以提出来。反正无论如何都是需要执行的。
判断b是否是奇数,只需要b和1相与就可以了。因为如果是奇数。二进制最后一位一定是1,和1相与结果就是真。如果是偶数,最后一位一定是0,和1相与就是假。
b整除2,我们二进制右移一位,效果就等价于除以2了。

c++版本

#include<iostream>
using namespace std;
int func(int a, int b, int k)
{
    int ans = 1;
    a %= k;
    while (b)
    {
        if (b & 1)
        {
            ans = (ans * a) % k;
        }
        a = (a * a) % k;
        b >>= 1;
    }
    return ans;
}
int main()
{
    cout << func(3, 2000, 7);
}

和python没什么区别。