洛谷题单指南-分治与倍增-P1226 【模板】快速幂
原题链接:https://www.luogu.com.cn/problem/P1226
题意解读:快速幂模版题。
解题思路:
1、分治法
要计算a^b,可以对b分情况讨论:
如果b是偶数,即b = 2t,a^b = a^t * a^t
如果b是奇数,即b = 2t + 1,a^b = a * a^t * a^t
很容易用递归实现
100分代码:
#include <bits/stdc++.h>
using namespace std;
int a, b, p;
//计算x^y%p
int ksm(int x, int y)
{
if(y == 0) return 1 % p;
int t = ksm(x, y / 2);
if(y % 2 == 0) return 1ll * t * t % p;
else return 1ll * x * t % p * 1ll * t % p;
}
int main()
{
cin >> a >> b >> p;
printf("%d^%d mod %d=%d", a, b, p, ksm(a, b));
}
2、倍增法
基于任意整数都可以转换成若干个2的次幂之和,如14 = 2^1 + 2^2 + 2^4
这样一来,计算a^b,如果b=14,可以变成计算a^(2^1 + 2^2 + 2^4)
由于15用二进制表示为1110,因此可以通过移位操作来枚举14的每一个2的次幂,累乘即可
每移位一次,指数的二进制位置所表示的值都是之前的2倍,要累乘的值a = a * a,如果当前位是1,说明需要累乘,如果当前位为0,说明不需要累乘
下面模拟一下过程:
设结果res = 1,计算a^14
第一次:判断1110 & 1 == 0,不需要累乘, 1110右移一位变成111,a = a * a,这时a是初始a^2,res = 1
第二次:判断111 & 1 == 1, 需要累乘,res = res * a, 111右移一位变成11,a = a * a,这时a是初始a^4,res = 初始a^2
第三次:判断11 & 1 == 1,需要累乘,res = res * a,11右移一位变成1,a = a * a,这时a是初始a^8,res = 初始a^2*初始a^4
第四次:判断1 & 1 == 1,需要累乘,res = res * a,1右移一位变成0,结束,res = 初始a^2 * 初始a^4 * 初始a^8 = 初始a^14
100分代码:
#include <bits/stdc++.h>
using namespace std;
int a, b, p;
//计算x^y%p
int ksm(int x, int y)
{
int res = 1;
while(y)
{
if(y & 1) res = 1ll * res * x % p;
y = y >> 1;
x = 1ll * x * x % p;
}
return res;
}
int main()
{
cin >> a >> b >> p;
printf("%d^%d mod %d=%d", a, b, p, ksm(a, b));
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?