Pascal程序笔迹:快速幂
来源:互联网 发布:鹰眼摄像头监控软件 编辑:程序博客网 时间:2024/06/07 01:23
<Pascal笔迹>>>快速幂
作者:A_Ender
[题目介绍]
求a的n次方除b的余数。
[样例输入,输出]
输入:1000000 100000 123231
输出:95734
[题目数据]
c<=b<=a<=31^2-1
{本题套路}
数据太大,会直接爆,普通的暴力完全不行。
{算法详解}
{1}这里使用到一个分治算法,将一个非常大的数据转化成一个个小数据。(乘号可以算是大数据与小数据的分界线)
如果n是基数,那么可以转换成[a^(n-1)*n]
如果n是偶数,那么又可以转换成[a^(n/2)*(a^2)]
{2}这是一个可以推理出来的公式。(乘号也可以算是大数据与小数据的分界线)
[a*b mod c=d]=[(a mod c)*(b mod c) mod c=d]
a和b可以看作是{1}的a^m和分化出来的数。
{3}基于{2}的公式,a和b可能会很大(当然不会有int64大),但用mod的话太慢了,所以这里判断偶数直接看个位是不是2的倍数就行了。
{算法演示}
3^13 [mod 4]
3^12*3
3^6*3*9
3^3*3*9
3^2*3*3*9
9*3*3*9
全部mod 4
1*3*3*1
总和[9]再mod 4
最后是1
<代码实现>
var
n,m,k,l:int64; //n,m,k分别为a,n,b l为下一次分化的数
function w(aa:int64):int64;//用字符串判断个位基偶
var
s:string;
begin
str(aa,s);
s:=s[length(s)]; //个位
if (s='0')or(s='2')or(s='4')or(s='6')or(s='8') then
exit(1)
else
exit(0);
end;
begin
l:=1;
read(n,m,k);
repeat
if w(m)=0 then //如果n是基数
begin
dec(m);
l:=l*(n mod k);
end
else
if w(m)=1 then //如果n是偶数
begin
m:=m div 2;
l:=l*(n*n mod k);
end;
l:=l mod k; //分化的也可能会大于b
until m<=2;
if m=2 then //再次判断(此部可以省略不看)
begin
l:=l*(n*n mod k);
l:=l mod k;
end;
if m=1 then
begin
l:=l*(n mod k);
l:=l mod k;
end;
write(l);
end.
- Pascal程序笔迹:快速幂
- Pascal程序笔迹:弧形判断
- Pascal程序笔迹:steve挖矿
- Pascal程序笔迹:和为零
- 快速排序pascal程序
- C++程序面试笔迹一
- C++程序面试笔迹二
- C++程序面试笔迹四
- C++程序面试笔迹五
- C++程序面试笔迹六
- 笔迹
- 笔迹
- pascal快速排序
- PASCAL基础-程序体
- 我是程序猿-Pascal
- 最大正数pascal程序
- 拼数pascal程序
- 纪念品分组pascal程序
- 51nod 1277 字符串中的最大值(KMP)
- 关于HTTP的知识(自己学习)
- 清橙A1094. 牛顿迭代法求方程的根
- easyui--3.layout
- ctf密码学——围在栅栏里的爱
- Pascal程序笔迹:快速幂
- @SerializedName
- 卷土重来:谷歌推出Datally新应用,适应中国消费市场
- 常用排序算法之直接插入排序
- easyui--4.tree
- PermissionsDispatcher
- 我(程序员?)
- ubuntu17.04中锐捷客户端登录问题
- 541. Reverse String II