快速幂加模

fast中x为底数,y为指数,c为模
如果题目数据刁钻的话,必须要在其中所有可以加模的地方加上
特别是x开始就需要模上。

#include<iostream>

using namespace std;
unsigned long long int sum ;

void fast(unsigned long long int x, unsigned long long int y, unsigned  long long int c) {
    sum = 1;
    x = x%c;
    while (y) {
        //if y is odd
        if (y & 1) sum = sum*x%c;
        y >>= 1;
        x = x*x%c;
    }
}
int main() {
    long long int x, y, c;
    while (scanf_s("%lld%lld%lld",&x,&y,&c)!=EOF) {
        fast(x, y, c);
        cout << sum << endl;
    }
}
<think>嗯,用户问的是快速幂版,我需要先回忆一下快速幂的基本概念应用场景。快速幂,也叫做二进制取幂,是一种用来高效计算大指数幂取的方法,比如计算a^b mod m。这在密算法或者大数计算中很常见,可以避免直接计算a^b导致数值过大。 首先,我应该解释快速幂的原理。快速幂的核心思想是将指数分解成二进制形式,然后通过迭代平方来减少计算次数。比如,计算a^13,13的二进制是1101,所以a^13 = a^8 * a^4 * a^1。这样原本需要13次乘法的计算,现在只需要几次平方乘法操作。 接下来要考虑的是如何将这个思路转化为代码。通常有两种实现方式:递归迭代。递归的方法可能更容易理解,但因为递归会有栈溢出的风险,所以在实际应用中可能更倾向于迭代方式。过用户要的是版,可能需要给出两种方法的代码示例? 然后,运算的问题。快速幂通常一起使用,特别是当结果可能很大的时候,所以版里应该包括每一步都取的操作,以避免数值溢出。比如,在每次平方或者乘法之后都对结果取,这样中间结果会过大。 用户可能需要的是直接给出代码示例,并且解释每个步骤的作用。所以,我应该先写一个迭代版本的快速幂函数,参数包括底数a,指数b,数m。然后解释循环中的每一步,比如当指数b当前位为1时,将结果乘以当前的a的幂次,然后a自乘,同时每一步都取。 另外,要注意处理边界情况,比如当m为1时,任何数取都是0,或者当指数b为0时,结果应该是1 mod m。这些情况需要在代码中处理吗?可能需要在代码的开头上条件判断,比如if m == 1,则直接返回0;如果b == 0,返回1%m。 现在,我需要确保代码的正确性。比如,假设用户输入a=2,b=10,m=1000,那么结果应该是24,因为2^10=1024 mod 1000=24。用代码验证的话,快速幂函数应该返回这个结果。 另外,递归版本的快速幂可能效率稍低,但结构更清晰。递归的终止条件是当指数为0时返回1,否则根据指数的奇偶性分解问题。同样每一步都要取。 但是用户可能更关注迭代版本,因为效率更高,而且没有栈溢出的问题。所以应该以迭代版本作为主要版。 然后,还需要说明快速幂的时间复杂度是O(log n),因为每次将指数除以二,所以循环次数是对数级别的。 最后,应用场景的举例,比如计算大指数取,或者矩阵快速幂等扩展应用。但用户的问题可能只需要基础的版,这部分可以作为补充说明。 总结下来,回答的结构应该是先介绍快速幂的作用,然后解释原理,接着给出迭代的代码版,解释代码的每一步,然后可能再给出递归版本作为补充,最后说明时间复杂度应用场景。同时,要注意代码的正确性,比如处理b=0m=1的情况,以及正确使用运算。</think>快速幂是一种高效计算大指数幂的算法,特别适用于对结果取的场景(如$a^b \mod m$)。其核心思想是通过**二进制分解指数**,将计算复杂度从$O(n)$降低到$O(\log n)$。以下是详细的实现版与解析: --- ### **一、快速幂的核心思想** 将指数$b$表示为二进制形式,例如$b = 13$(二进制为$1101$),则: $$ a^{13} = a^{8} \cdot a^{4} \cdot a^{1} $$ 通过迭代平方逐步计算$a^{2^k}$,并根据二进制位是否为1决定是否累乘到结果中。 --- ### **二、迭代法版(推荐)** ```python def fast_pow(a: int, b: int, m: int) -> int: result = 1 a = a % m # 初始取防止a过大 if m == 1: return 0 # 任何数对1取均为0 while b > 0: if b % 2 == 1: # 当前二进制位为1,累乘结果 result = (result * a) % m a = (a * a) % m # 平方更新底数 b = b // 2 # 右移二进制位 return result ``` #### **关键步骤解析** 1. **初始化结果**:`result = 1`,因为$a^0 = 1$。 2. **循环分解指数**:通过`b = b // 2`逐位处理二进制。 3. **累乘条件**:若当前二进制位为1(即`b % 2 == 1`),将当前$a^{2^k}$乘入结果。 4. **平方更新底数**:每次循环底数$a$平方(对应二进制位的权值)。 --- ### **三、递归法版(辅助理解)** ```python def fast_pow_recursive(a: int, b: int, m: int) -> int: if b == 0: return 1 % m temp = fast_pow_recursive(a, b // 2, m) temp = (temp * temp) % m if b % 2 == 1: temp = (temp * a) % m return temp ``` #### **递归逻辑** 1. **终止条件**:当$b=0$时返回$1 \mod m$。 2. **分治思想**:将$a^b$拆分为$a^{b/2} \cdot a^{b/2}$,若$b$为奇数则额外乘$a$。 --- ### **四、时间复杂度** - **迭代法**:$O(\log b)$,循环次数等于二进制位数。 - **递归法**:$O(\log b)$,但存在函数调用栈开销。 --- ### **五、应用场景** 1. **大数取**:如计算$2^{100} \mod 1000$,直接计算会溢出,快速幂只需7次循环。 2. **密码学**:RSA密等算法中的幂运算。 3. **矩阵快速幂**:扩展后可高效计算矩阵的高次幂。 --- ### **六、示例验证** 计算$3^{10} \mod 1000$: 1. 初始:`result=1`, `a=3`, `b=10` 2. 循环过程: - `b=10`(偶数):`a=9`, `b=5` - `b=5`(奇数):`result=9`, `a=81`, `b=2` - `b=2`(偶数):`a=6561%1000=561`, `b=1` - `b=1`(奇数):`result=9*561=5049%1000=49`, `a=561^2%1000=721`, `b=0` 3. 最终结果:$49$。 --- 掌握此版后,可高效处理大指数运算问题,同时避免数值溢出风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值