当前位置: 首页 > ai >正文

经典算法复习——快速模幂

茶话会

终于回到了正业上。不知道蓝桥杯啥时候第二阶段,反正接近一个月一直在数学建模数学建模,真的给我打吐了,时不时还有乱七八糟的小组作业来恶心我。数学建模到一定瓶颈很难突破下去,除了熟练写论文也没什么实际意义,至于一些别的比如创赛。。。懂的都懂,知识学不到一点。我真的有点佩服把这么深奥的底层逻辑用独立的一套语言表示出来的这种行为,你知道这是什么,但我也肯定你绝对不知道是什么。

还是算法好,A出来了的就是实打实的会了。。。

模幂运算

幂运算不必多说是什么。取模防止结果过大,每一步计算结果都要取模。

那现在的问题是,怎么“快速”呢?

比如2^15不是老老实实算15次就行吗?

错啦!我直接摆一个公式:2^15=2^8*2^4*2^2*2^1

而在这里,2^2可以由2^1算出来,2^4可以由2^2算出来,2^8可以由2^4算出来。

这样就避免了很多重复性的计算,这就是快速幂的核心思想。

而15的二进制表示为1111,那么2的1次方到4次方全员参与进来计算。

看完这些,如果你还不太理解,那么把15换成13(1101)

2^15=2^8*2^2*2^1,中间的2^4没得乘了,因此你的指数的二进制要控制它成不成本身。

总结一下流程:

计算a^b mod n,我们初始化一个ans=1,然后进入一个循环:

我们需要加一个判定,就是b要掌控你的结果乘不乘现在的a。

掌控方式就是b%2==1,也就是现在的b对2取余为几。

底数a再自乘,也就是a=a*a;

b再除2赋给自己。

经常沉迷在洛谷力扣等地方的同学可以发现,b%2输出一个结果,再进行b/=2,这样循环,恰好就是b的二进制表示的倒过来的结果。这也正是我们希望的a指数级增长的意图。

如果你还不懂:

取a=2 b=13 n=10086(你在理解这段的时候就先别管模运算了),赋ans=1。

判断条件ansab
13%2==12^12^26
6%2==02^12^43
3%2==12^1*2^42^81
1%2==12^1*2^4*2^82^160

纯保姆级教学啊,快点个赞!

代码

//现在写的
#include<iostream>
using namespace std;
long long a,b,n;
long long quickpower();
int main()
{cin>>a>>b>>n;cout<<quickpower();return 0;
}long long quickpower()
{long long ans=1;while(b!=0){if(b%2==1)ans=ans*a%n;a=a*a%n;b/=2;//cout<<ans<<' '<<a<<' '<<b<<endl;}return ans;
}//一年前写的
/*#include <stdio.h>
long long quickpower(long long a, long long b, long long p);
int main()
{long long a, b, p;scanf("%lld%lld%lld", &a, &b, &p);long long res = quickpower(a, b, p) % p;printf("%lld^%lld mod %lld=%lld", a, b, p, res);return 0;
}
//快速幂:一个数取余并且不断对2除,逆序结果就是2进制码
long long quickpower(long long a, long long b, long long p)//a的b次幂  a15=(a7)*(a7)*a  a7=(a3)*(a3)*a  a3=(a1)*(a1)*a1  
{long long x = a, ans = 1;//递归while (b > 0) {if (b % 2 == 1)ans = ans * x % p;x = x * x % p;b /= 2;}return ans % p;
}*/

http://www.xdnf.cn/news/7351.html

相关文章:

  • 51单片机点亮一个LED介绍
  • C++ 函数对象、仿函数与 Lambda 表达式详解
  • 12.vue整合springboot首页显示数据库表-实现按钮:【添加修改删除查询】
  • 深入Java G1 GC调优:如何解决高延迟与吞吐量瓶颈
  • 嵌入式学习笔记 - STM32独立看门狗IWDG与窗口看门狗WWDG的区别
  • HTTPS实验室——TLS/TLCP一站式解决方案
  • C语言——深入理解指针(一)
  • rosbag使用记录
  • 搭建一个永久免费的博客
  • Java设计模式之组合模式:从入门到精通(保姆级教程)
  • Java 泛型详解
  • 黄仁勋Computex演讲:将于三季度推出下一代GB300系统,个人AI计算机DGX Spark已全面投产
  • 进程和线程有什么区别?多线程有什么优缺点?线程的创建方式有哪些?如何简单的使用线程?用户线程和守护线程有什么区别?start 和 run 方法有什么区别?
  • go 与面向对象编程(OOP)
  • 设置IDEA打开新项目使用JDK17
  • 【OpenCV基础2】图像运算、水印、加密、摄像头
  • 信号量基础入门:并发控制的核心概念
  • BGP选路
  • 常用ECSQL整理
  • ‌AT6558R-5N22北斗B1I单频导航芯片
  • 《深入理解数组名:sizeof(arr)、arr 和 arr 的区别》
  • 三种嵌入式开发常用的组网方式
  • 【C++】C++的IO流
  • 青岛地铁二号线列车运行图优化系统
  • AIGC与文本生成:人工智能写作的新纪元
  • Adminer:一个基于Web的轻量级数据库管理工具
  • Python | 需求预测模型
  • 使用 docker-volume-backup 备份 Docker 卷
  • plc基础知识整理(三菱)
  • PHP 实现连续子数组的最大和、整数中1出现的次数