【快速幂模板】原理实现详细讲解

在这里插入图片描述
模板就是这么个模板,没什么思路可讲,数学原理是幂数运算法则,具体细节讲解在代码注释里。

import java.util.Scanner;

public class 快速幂 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int a=sc.nextInt();
        int b=sc.nextInt();
        int p=sc.nextInt();
        int ans=qmi(a,b,p);
        //int res=test(7);
        System.out.println(ans);
        //System.out.println("10进制数在二进制状态下的转化"+res);
    }
//对比学习
    private static int test(int i) {//位运算模拟2进制转化为10进制的过程。
        int res=0;
        int a=1;
        while(i>0){
            if((i&1)==1){
                res+=a;//与快速幂不同的是这个只需相加就能得到结果,(7=1+2+4)幂需要乘底数a
            }
            a=a*2;
            i>>=1;
        }
        return res;
    }
//java要考虑溢出
    private static int qmi(int a, int b, int p) {//数学原理:a^b1*a^b2=a^(b1+b2),b1+b2=b;
        // b可以拆分,加减拆分联想到二进制表达法,3^5=3^1*3^4(5=1+4); 二进制:1+2+4+...任何一个数都可以用二进制表达出来。
        int res=1%p;
        while(b>0){//整体模拟b的二进制表达过程
            if((b&1)==1){
                res=(int)((res * 1L * a) % p);//当二进制表达是1时需要乘上结果
            }
            //为什么直接用Long不行?
            a=(int)((a * 1L * a) % p);//相当于二进制每次左移扩大就平方一次,即要完成二进制可以表达出b值的位数。
            //3^5,5=101,位运算从低到高,遇到1就将答案乘上a,不管是不是1,都需要a*a来模拟二进制的递增形成
            b>>=1;
        }
        return res;
    }
}

注意:如果是c或c++写法的话,不需要1L,其他写法是一样的,只有Java才会出现溢出的情况!!!这个1L真的很重要,如果没有这个,当数据一定大的情况下内存溢出,会出现负数结果,数据只能通过三个测试点!!
突然发现去年13届蓝桥杯第一道签到题为什么写错了,自己的快速幂模板本身没有错误,但计算数据过大,用Java写内存溢出了,当时没有用Java测试过超大数据,导致结果算错,但凡过一遍测试,或者用库函数写,,,┭┮﹏┭┮。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值