JAVA大数问题

大数求余问题

  • 当求解x的a次幂时,可能会出现大数越界的问题,超出int32位,所以很多题目要求对结果进行1000000007的取余,这个数字在int32的范围之内
  • 1000000007的平方超出了int32的范围,但是在long64的范围之内

思路:

(a+b)%c=(a%c+b%c)%c
a % c = ( a % c ) % c
( a b ) % c = [ ( a % c ) ( b % c ) ] % c

1.循环求余法

利用循环操作一次求得X的一次方,二次方,…,a次方对P的余数,保证每一轮中间求得的余数都在32位整数范围内:

def remainder(x,a,p):
	"""
	rem = x^a % p
	"""
	rem = 1
	for _ in range(a):
		rem = (rem * x) % p
	return rem

2.快速幂求余法

在这里插入图片描述

# 求 (x^a) % p —— 快速幂求余
def remainder(x, a, p):
    rem = 1
    while a > 0:
        if a % 2: rem = (rem * x) % p
        x = x ** 2 % p
        a //= 2
    return rem

剪绳子的大数问题

循环求余:

// 求 (x^a) % p —— 循环求余法。固定搭配建议背诵
   public long  remainder(int x,int a,int p){  //x为底数,a为幂,p为要取的模
        long rem = 1 ;
        for (int i = 0; i < a; i++) {
            rem = (rem * x) % p ;   
        }
        return rem;
    }
class Solution {
   public int cuttingRope(int n) {
        if(n <= 3) return n - 1;
        int b = n % 3, p = 1000000007;

        long rem = 1, x = 3 ,a = n / 3;
        //直接套循环求余公式
        for(int i = 0; i < ((b == 1)?a-1:a); i++) { //b == 1代表余数为1的时候,需要单独取出一个3出来凑成2*2达到最大值效果
            rem = (rem * x) % p;
        }  
        if(b == 0) return (int)(rem % p);
        if(b == 1) return (int)(rem * 4 % p);
        return (int)(rem * 2 % p);
    }

快速幂求余:

这个比较难理解

class Solution {
    public int cuttingRope(int n) {
        if(n <= 3) return n - 1;
        int b = n % 3, p = 1000000007;
        long rem = 1, x = 3;
        for(int a = n / 3 - 1; a > 0; a /= 2) {
            if(a % 2 == 1) rem = (rem * x) % p;
            x = (x * x) % p;
        }
        if(b == 0) return (int)(rem * 3 % p);
        if(b == 1) return (int)(rem * 4 % p);
        return (int)(rem * 6 % p);
    }
}

Python 代码: 由于语言特性,理论上 Python 中的变量取值范围由系统内存大小决定(无限大),因此在 Python 中其实不用考虑大数越界问题。
Java 代码: 根据二分法计算原理,至少要保证变量 x 和 rem 可以正确存储 1000000007^2,而 2^{64} > 1000000007^2 > 2^{32} ,因此我们选取 long 类型。


今日推歌

-----《互不打扰》陈之

还在念念不忘 是你给的好
故事很短 回忆却满是欢笑
如果当初 换你煎熬
你会不会体会 我的渺小
互不打扰 是我们最后的习惯
你的名字 是我一生的温暖
从此平淡 诸事无关

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

星回昭以烂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值