快速幂 模板题

题目描述
输入b,p,k的值,求b^p mod k的值。其中b,p,k*k为长整型数。
输入输出格式
输入格式:
三个整数b,p,k.
输出格式:
输出“b^p mod k=s”
s为运算结果
输入输出样例
输入样例1:
2 10 9
输出样例1:
2^10 mod 9=7

很显然,这是一道很明白的快速幂。
当然,我们要确定的是,若是a%b=c,则a^2≡c^2(mod b),以及乘法也有这样的性质,如a×p≡c×p(mod b)。
证明:设a=b×q+c,则a^2=(bq+c)^2=b^2×q^2+2bcq+c^2.
因为 多项式b^2×q^2+2bcq+c^2 前两项均含有系数b,所以易知 a^2≡c^2 (mod b)
同样,a×p=bpq+cp,因为bpq项含有b,因此a×p≡c×p (mod b)
所以,我们在求取快速幂时,可以不断的取模以防止其越界。
如题目2^10求取快速幂,我们可以先从暴力改进,不断乘十个二。
因此,我们得到答案ans=1×2×2×2×2×2×2×2×2×2×2.
然后再对它进行快速幂的优化。
因为ans=1×2^10=1×(2^2)^5
然后,我们发现外面的5并不是一个偶数,我们就将其提取出来,得到
ans=1×2^2×(2^2)^4=4×((2^2)^2)^2=4×16^2
然后发现16竟然超过了k,我们就对它取模运算一下,所以
ans=4×7^2=4×49=4×(9×5+4)
∵4×(9×5+4)≡4×4 (mod 9)
所以有ans=16,又有16≡7(mod 9)
最后得到ans为7.
故此,我们可以发现,我们在进行快速幂运算时,当幂为偶数时,则减半并将待乘的数平方;当幂为奇数,则乘以待乘的数,并将幂减半,将待乘的数平方。直到幂为1为止。
代码如下:

#include <bits/stdc++.h>

#define LL long long 

using namespace std;

LL b,p,k,ans=1;

int main()
{
    scanf("%lld%lld%lld",&b,&p,&k);
    printf("%lld^%lld mod %lld=",b,p,k);
    while (p)
    {
        if (p&1)
            (ans*=b)%=k;
        (b*=b)%=k;
        p>>=1;
    }
    ans%=k;
    printf("%lld",ans);
}

猜你喜欢

转载自blog.csdn.net/CutieDeng/article/details/81946435