洛谷P1226 【模板】快速幂
1.洛谷P5707 【深基2.例12】上学迟到2.洛谷P5710 【深基3.例2】数的性质3.洛谷P1914 小书童——凯撒密码4.洛谷P1047 [NOIP2005 普及组]校门外的树5.洛谷P5728 【深基5.例5】旗鼓相当的对手6.洛谷P5721 【深基4.例6】数字直角三角形7.洛谷[NOIP2015 普及组] 金币8.洛谷[NOIP2011 普及组]数字反转9.洛谷P4956 [COCI2017-2018#6] Davor10.洛谷B3843 [GESP202306 三级]密码合规11.洛谷P1601 A+B Problem(高精度加法)12.洛谷P1614 爱与愁的心痛(滑动窗口解法)13.洛谷P2670 [NOIP2015 普及组] 扫雷游戏14.洛谷P1563 [NOIP2016 提高组] 玩具谜题15.洛谷B3849 [GESP样题 三级] 进制转换16.洛谷P1100 高低位交换17.洛谷P1143 进制转换18.[NOIP2008 提高组] 笨小猴(洛谷题号P1125)19.洛谷[NOIP2015 普及组] 金币20.洛谷P3383 【模板】线性筛素数21.洛谷P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题22.洛谷B3940 [GESP样题 四级] 填幻方23.洛谷P1042 [NOIP2003 普及组] 乒乓球24.洛谷P1067 [NOIP2009 普及组] 多项式输出25.洛谷P1098 [NOIP2007 提高组] 字符串的展开26.洛谷P1842 [USACO05NOV] 奶牛玩杂技27.洛谷P1223 排队接水28.洛谷P1209修理牛棚 Barn Repair29.洛谷P5250 【深基17.例5】木材仓库
30.洛谷P1226 【模板】快速幂
31.洛谷P1480 A/B Problem32.洛谷P1786 帮贡排序33.双指针习题:Kalindrome Array1.快速幂模板
前置知识
一个数字n,它的二进制位数一定是log2n向下取整+1;
快速幂模板代码
这段代码实现了快速幂算法(Exponentiation by squaring),用来计算 ( an ) 的值,其中 ( a ) 和 ( n ) 都是整数。
int quickpow(int a, int n) { int res = 1; // 初始化结果为1,因为任何数的0次幂都是1 while (n) { // 当指数n不为0时,继续执行循环 if (n & 1) // 如果n的最低位为1(即n是奇数) res = res * a; // 将当前底数a乘到结果中 a = a * a; // 将底数a平方,相当于底数翻倍,指数减半 n >>= 1; // 将指数n右移一位,相当于将指数减半 } return res; // 返回计算结果 }
现在逐句解析每一行代码的作用:
-
int res = 1;
- 初始化变量
res
为1,这是最终结果的初始值。任何数的0次幂都是1。
- 初始化变量
-
while (n) {
- 进入一个循环,条件是当指数
n
不为0时继续执行。循环将持续执行直到n
变为0。
- 进入一个循环,条件是当指数
-
if (n & 1)
- 判断当前的指数
n
是否为奇数,使用位运算n & 1
来判断。如果n
的最低位(即最右边的二进制位)为1,则说明n
是奇数。
- 判断当前的指数
-
res = res * a;
- 如果
n
是奇数,则将当前的底数a
乘到结果res
中。这步实现了快速幂算法中的乘法操作。
- 如果
-
a = a * a;
- 然后将底数
a
自乘,即a
变成a^2
。这一步相当于将底数翻倍,对应于指数减半的操作。
- 然后将底数
-
n >>= 1;
- 将指数
n
右移一位,即n
变成n / 2
。这一步实现了快速幂算法中的指数减半操作。
- 将指数
-
循环回到第2步,直到
n
变为0,退出循环。 -
return res;
- 返回最终计算得到的结果
res
,即底数a
的指数n
次幂的值。
- 返回最终计算得到的结果
这段代码利用了快速幂算法的思想,通过迭代和位运算的方式,将指数的计算复杂度从 ( O(n) ) 优化到 ( O(log n) ),显著提高了计算效率。
快速幂算法的形象解释
快速幂算法的例题
【模板】快速幂
题目描述
给你三个整数
输入格式
输入只有一行三个整数,分别代表
输出格式
输出一行一个字符串 a^b mod p=s
,其中
样例 #1
样例输入 #1
2 10 9
样例输出 #1
2^10 mod 9=7
提示
样例解释
数据规模与约定
对于
答案
这题直接套用快速幂算法的模板,只需要每一步我们加上取模运算即可,注意数据需要开long long类型
#include<iostream> using namespace std; long long quickpow(long long a, long long n,long long p) { long long res = 1; while (n) { if (n & 1) res = (res * a)%p; a = (a * a)%p; n >>= 1; } return res; } int main() { long long a, b, p; cin >> a >> b >> p; printf("%lld^%lld mod %lld=%lld", a, b, p, quickpow(a, b, p)); return 0; }
合集:
洛谷
分类:
洛谷 / 基础数学问题
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战