快速乘法/幂 算法详解_(a * b) % mod-程序员宅基地

技术标签: 快速乘法  ACM_数论  数论  快速幂  ACM  位运算  

快速乘法/幂 算法详解


适用范围:快速计算a*b % mod的结果(主要目的是换乘法为加法,防止爆数据),或者快速计算a^b % mod 的结果,时间复杂度大大降低。

算法描述:首先你可能会问a*b不是直接乘就出来了么,为什么需要快速算法?但是乘法在计算机中处理的时间并不是这么快的,也要拆分为加法来做的。所以快速乘法会更快的计算a*b的结果,而且a*b%mod可能还没取模就已经爆long long,但快速乘法却不会。快速幂也是同样的道理。

实现的原理都是基于按照二进制位一步一步乘来避免重复的操作,利用前面的中间结果,从而实现快速的目的。

对于乘数b来说,势必可以拆成2进制,比如110101。有一些位为0,有一些位为1。根据乘法分配律:a*b=a*(b1+b2+b3+……
那么对于a*53 = a*110101(二进制)= a*(100000+10000+100+1)=a*(100000*1+10000*1+1000*0+100*1+10*0+1*1)。
那么设立一个ans=0用于保存答案,每一位让a*=2,在根据b的对应为1看是不是加上此时的a,即可完成快速运算。比如刚才的例子让a=5,运转流程如下。


即可计算出5*53=265。

不知道看到这里你发现了没有,其实对于快速幂其实是一样的道理,只不过每一位a更新的时候不是*2,而是a=a*a,ans+变成ans*。
例如3^9的流程如下:3^5=3^(1001) (二进制)= 3^(1000*1+100*0+10*0+1*1)

最后说一些细节吧,如果要取模在ans+、ans*、和a更新的时候都%mod即可。然后b一位一位的读取每次b/=2或者b>>=1,表示b向右移动一位,再与1做&操作即可。(见代码)

上代码:
#include <iostream> 
#include <cstdio> 
#include <algorithm>  
#include <cmath>  
#include <cstring>  
#include <map>  
using namespace std;

long long q_mul( long long a, long long b, long long mod ) //快速计算 (a*b) % mod
{
	long long ans = 0;	// 初始化
	while(b)				//根据b的每一位看加不加当前a
	{
		if(b & 1)			//如果当前位为1
		{
			b--;
			ans =(ans+ a)%mod;   //ans+=a
		}
		b /= 2;							//b向前移位
		a = (a + a) % mod;			//更新a

	}
	return ans;
}

long long q_pow( long long a, long long b, long long mod ) //快速计算 (a^b) % mod
{
	long long ans = 1; // 初始化
	while(b)//根据b的每一位看乘不乘当前a
	{
		if(b & 1)	//如果当前位为1
		{
			ans = q_mul( ans, a, mod ); //ans*=a
		}
		b /= 2;										//b向前移位
		a = q_mul( a, a, mod );			//更新a
	}
	return ans;
}


int main( )
{
	long long a, b, n;
	while(cin >> a >> b >> n)
	{
		cout << "a*b%n = " << q_mul( a, b, n ) << endl;
		cout << "a^b%n = " << q_pow( a, b, n ) << endl;
	}
	return 0;
}

好了,五一节就这么结束了,又要开学啦,,烦躁。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/maxichu/article/details/45459715

智能推荐

合宙ESP32C3基于VSCode PIO Arduino开发框架初探教程_合宙esp32 c3更换flash-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏43次。合宙ESP32C3基于VSCode PIO Arduino开发框架初探教程_合宙esp32 c3更换flash

Julia 并发编程 ---- @distributed 和 pmap的区别-程序员宅基地

文章浏览阅读1.2k次。目录1、功能说明2、代码用例2.1 使用 @distributed2.2 使用pmap3、总结1、功能说明@distributed(Julia 0.6之前用@parallel)会立即把要做的工作平均分配给所有的workers。注意,在@distributed中,会在指定范围在根据所有的worker的个数分片。相比之下,pmap将启动每个worker的工作,并根据w...

UE4如何检测目标在锥形视野内_unreal 计算目标是否在视锥体内-程序员宅基地

文章浏览阅读9.4k次,点赞5次,收藏15次。做UE4游戏AI方面经常会遇到一个问题,就是何如判定目标在AI单位的视野范围内,假如我们现在要检测玩家在AI单位的前方60°夹角的视野范围内,如果在的话就把玩家设置为该AI单位的目标。我做了一个简单的Service节点来处理,如图这两大图可能看不清,我把图分开又截了2张。 当然这个简单节点中没有检测两者之间的距离,如果要实际应用肯定还要加..._unreal 计算目标是否在视锥体内

latex排版笔记_winedt 11-程序员宅基地

文章浏览阅读459次。latex写的格式不需要自己调,和编程差不多。关于latex和winedt的关系请参考百度:winedt 定义:  WinEdt软件是一个Windows平台下的强大的通用文本编辑器,其更倾向于LaTeX/TeX文档的编辑  latex定义:  LaTeX(LATEX,音译“拉泰赫”)是一种基于ΤΕΧ的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在20世纪80_winedt 11

TabLayout ViewPager fragment 联动_tablayout fragment绑定后如何联动 java android-程序员宅基地

文章浏览阅读245次。首先先看效果图:具体实现:首先导入依赖包:compile 'com.android.support:design:27.+'布局文件:&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;RelativeLayout ="http://schemas.android.com/apk/res/android" xmlns:..._tablayout fragment绑定后如何联动 java android

ffmpeg 编码生成mp4文件大小 码率控制_ffmpeg保存mp4设置码率-程序员宅基地

文章浏览阅读1.2w次,点赞6次,收藏14次。AVCodecContext* pCodecCtx = m_stVideoStream.pStream->codec; JP_ASSERT(NULL != pCodecCtx); pCodecCtx->codec_id = eVideoCodecId; pCodecCtx->gop_size = 1_ffmpeg保存mp4设置码率

随便推点

exec函数用法总结_exec用法-程序员宅基地

文章浏览阅读7w次,点赞81次,收藏411次。1. exec函数说明fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程不共享这些存储空间。linux将复制父进程的地址空间内容给子进程,因此,子进程由了独立的地址空间。),也就是这两个进程做完全相同的事。在fork后的子进程中使用exec_exec用法

MyBatis xml文件动态生成对象,网上找的自己进行了优化。_xmlmapperbuilder 可以动态添加吗-程序员宅基地

文章浏览阅读1k次。package com.*****.service.sys.jdbcApi.impl;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.lang.ref_xmlmapperbuilder 可以动态添加吗

10.10上下文菜单与上下文操作模式。_10、控制上下文菜单和粘贴-程序员宅基地

文章浏览阅读659次。目的:为应用实现长按列表项删除crime记录功能。3.0版本前(旧)是在浮动上下文菜单实现3.0版本后(新)在上下文操作栏呈现。为兼容API级别,必须定义一种菜单资源,和两组回调方法(新旧各一种)。18.2.1菜单资源:在res/menu中新建菜单资源文件。 android:icon="@android:drawable/ic_menu_dele_10、控制上下文菜单和粘贴

python如何将列表中的每个数字都保留两位有效数字_python中的使得表格某列的数字全部保留两位小数-程序员宅基地

文章浏览阅读2.2w次,点赞21次,收藏45次。如何将list中的每个数字都保留两位有效数字关键:首先,将list转为numpy数组,然后对numpy进行操作,最后对操作完成的numpy再转为数组。直接附代码list_ori = list(pixel_real_recognition_value) #原始列表mid_np = np.array(list_ori) #列表转数组mid_np_2f =..._python中的使得表格某列的数字全部保留两位小数

native层实现touch事件转key事件_touchinputmapper::dispatchmotion-程序员宅基地

文章浏览阅读572次。需求 最近公司来了一个需求,需要将touch事件转成key事件,只针对滑动事件与触摸事件。需求分析 首先这个需求是可以在kernel里面做的,由于我们没有kernel代码,因此这个方案就被pass掉了。第二个想到的是在java层做,想找一个拦截touch事件的方法,类似PhoneWindowMananger中拦截key事件的方法,可是没找到,找到的地方都已经到app层了,这样就可能有点..._touchinputmapper::dispatchmotion

python视图ajax请求,python之 使用 flask Blueprint(蓝图) 接收前台的ajax的post请求,报405 METHOD NOT ALLOWED错误的解决办法...-程序员宅基地

文章浏览阅读516次。在利用flask进行python的项目的开发过程中,做到了注册这一块,在前台利用ajax+post请求的时候,报了405 METHOD NOT ALLOWED的错误。网上的解决办法乱搜了一通,试了好久,均没有解决405 METHOD NOT ALLOWED这个问题。image.png和报错相关的文件代码(passport.py文件)如下@api.route("/users", methods=['..._flask 错误处理 ajax

推荐文章

热门文章

相关标签