洛谷P1226 【模板】快速幂

【模板】快速幂

题目描述

给你三个整数 a,b,pa,b,pa,b,p,求 ab mod pa^b \bmod pabmodp

输入格式

输入只有一行三个整数,分别代表 a,b,pa,b,pa,b,p

输出格式

输出一行一个字符串 a^b mod p=s,其中 a,b,pa,b,pa,b,p 分别为题目给定的值, sss 为运算结果。

样例 #1

样例输入 #1

2 10 9

样例输出 #1

2^10 mod 9=7

提示

样例解释

210=10242^{10} = 1024210=10241024 mod 9=71024 \bmod 9 = 71024mod9=7

数据规模与约定

对于 100%100\%100% 的数据,保证 0≤a,b<2310\le a,b < 2^{31}0a,b<231a+b>0a+b>0a+b>02≤p<2312 \leq p \lt 2^{31}2p<231

首先讲一下快速幂的好处:
1:可以实现边运算,边取模,可以让一些数据规模庞大的保持在long long的范围内。
2:复杂度是可以实现O(log n)的,比起C++自带的pow函数快多了,不用担心超时。
接下来讲快速幂的原理:
对于任意整数 a 和非负整数 n,可以将 a^n 分解为 a^(n/2) * a^(n/2)。通过递归调用快速幂算法,可以将计算次数从 n 降低到 n/2,从而大大减少了计算量。当 n 为奇数时,可以通过多乘一个 a 来补全。‌
快速幂的实现方法通常使用递归或迭代的方式。
最后就上代码了,毕竟是到板子题,也没啥好说。

Code

#include<bits/stdc++.h>
using namespace std;
long long b,c,d;
long long ans;
int power(int a,int n){
	int ans=1;
	while(n){
		if(n%2){
			ans=(ans%d)*(a%d)%d;
		}
		a=(a%d)*(a%d)%d;
		n/=2;
	}
	return ans;
}
int main(){
	cin>>b>>c>>d;
	ans=power(b,c);
	cout<<b<<'^'<<c<<" mod "<<d<<'='<<ans;
	return 0;
}
快速幂是一种高效的计算幂运算的算法,特别适用于大指数的情况。它利用了分治的思想,将指数分解为二进制形式,并逐步计算基数的平方,从而将时间复杂度从 $ O(n) $ 降低到 $ O(\log n) $。以下是一些与快速幂相关的题目及其解析。 ### P1226模板快速幂||取余运算 该题要求计算 $ a^b \mod p $,其中 $ a $、$ b $ 和 $ p $ 均为大数。直接计算 $ a^b $ 会导致溢出,因此需要使用快速幂算法并结合模运算的性质进行优化。 快速幂的基本思想是将指数 $ b $ 分解为二进制形式,并逐步计算 $ a $ 的平方。例如,计算 $ a^b $ 时,可以将 $ b $ 分解为 $ b = 2^{k_1} + 2^{k_2} + \cdots + 2^{k_n} $,然后依次计算 $ a^{2^{k_1}} $、$ a^{2^{k_2}} $ 等,并将这些结果相乘。 以下是一个实现快速幂的示例代码: ```cpp long long quick_pow(long long a, long long b, long long p) { long long result = 1; a = a % p; // 对a取模,避免溢出 while (b > 0) { if (b & 1) { result = (result * a) % p; // 如果当前位为1,乘入结果 } a = (a * a) % p; // 基数平方 b = b >> 1; // 右移一位 } return result; } ``` ### P1010 幂次方 这道题要求将一个整数表示为若干个 $ 2 $ 的幂次方的和。例如,$ 137 $ 可以表示为 $ 2^7 + 2^3 + 2^0 $。题目还要求将结果以特定格式输出,如 $ 2(7)+2(3)+2(0) $。 为了实现这一目标,可以使用递归的方法。首先预计算 $ 2 $ 的幂次方值,然后从最大的幂次方开始递归分解。例如,对于 $ 137 $,可以找到最大的 $ 2^7 $,然后递归处理 $ 137 - 2^7 = 9 $,依此类推。 以下是一个实现该逻辑的示例代码: ```cpp #include <bits/stdc++.h> using namespace std; int mark[20] = {1}; // 存储2的幂次方值,初始化为1(2^0) // 递归函数,将数字n表示为2的幂次方和的形式 void f(int n) { int flag = 0; // 用于标记最大的幂次 // 找到不超过n的最大2的幂次方 while (n >= mark[flag]) flag++; flag--; // 回退到合适的幂次 // 根据不同的幂次进行输出 if (flag == 1) cout << "2"; // 2^1直接输出2 else { if (flag == 0) cout << "2(0)"; // 2^0输出2(0) else { cout << "2("; // 更高次幂需要递归处理 f(flag); // 递归处理幂次 cout << ")"; } } // 减去已处理的部分,继续处理剩余数值 n -= mark[flag]; if (n != 0) { cout << "+"; // 还有剩余数值时输出加号 f(n); // 递归处理剩余部分 } } int main() { int n; // 输入的数字 cin >> n; // 预计算2的0到16次方 for (int i = 1; i < 17; i++) { mark[i] = mark[i - 1] * 2; } // 调用递归函数进行分解 f(n); return 0; // 程序正常结束 } ``` ### B2075 幂的末尾 这道题要求计算 $ a^b $ 的最后三位数。由于 $ a $ 和 $ b $ 可能非常大,因此需要使用快速幂算法,并在每一步中对结果取模 $ 1000 $,以避免溢出。 以下是一个实现该逻辑的示例代码: ```cpp #include <stdio.h> long long qp(long long a, long long b) { if (b == 0) return 1; if (b == 1) return a % 1000; long long r = qp(a, b / 2) % 1000; r = r * r % 1000; if (b % 2) r = r * a % 1000; return r; } int main(void) { long long a, b; scanf("%lld %lld", &a, &b); long long x = qp(a, b); printf("%03lld", x); return 0; } ``` ### 题:越狱问题【快速幂】 这道题涉及快速幂的应用,用于解决大指数幂运算的问题。通过快速幂算法,可以高效地计算 $ a^b \mod p $,从而避免超时。 快速幂的核心思想是将指数分解为二进制形式,并逐步计算基数的平方。例如,计算 $ a^b $ 时,可以将 $ b $ 分解为 $ b = 2^{k_1} + 2^{k_2} + \cdots + 2^{k_n} $,然后依次计算 $ a^{2^{k_1}} $、$ a^{2^{k_2}} $ 等,并将这些结果相乘。 ### 相关问题 1. 如何使用快速幂算法计算 $ a^b \mod p $? 2. 如何将一个整数表示为 $ 2 $ 的幂次方的和? 3. 如何计算 $ a^b $ 的最后三位数? 4. 快速幂算法的时间复杂度是多少? 5. 快速幂算法在哪些场景下特别有用?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值