前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >快速幂的大数运算_快速幂模

快速幂的大数运算_快速幂模

作者头像
全栈程序员站长
发布2022-11-16 16:42:41
8100
发布2022-11-16 16:42:41
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

快速幂运算

1.什么是快速幂

快速幂,是指在进行幂运算的时候,用一种快速方法得出答案。比如,要求2^100的值,那按照最简单的方式,就是一个一个2去相乘,然后最终得到答案,那么这样就要计算100次,非常浪费时间,那么快速幂就是使用一种技巧使得将其计算次数减少,快速得到答案。

2.快速幂的“小数”运算

对于系统内置类型的整型,暂且叫他“小数”,这个时候进行快速幂运算,代码如下:

代码语言:javascript
复制
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const long long int mod = 1000000000007;   //对答案取模
int main()
{ 

long long int n;
long long int ans = 1;
long long int temp = 2;
cin >> n;   //求2的n次方
printf("2的%lld次幂对对1000000000007取模的最终值是:", n);
while (n > 0)  //快速幂模板
{ 

if (n%2 == 1)
ans = (ans%mod * temp%mod) % mod;
n /= 2;
temp = (temp % mod * temp % mod)%mod;
}
printf("%lld",ans%mod);
return 0;
}

那么快速幂的原理是什么呢? 用一张图来表示

在这里插入图片描述
在这里插入图片描述

3.高精度(大数)的快速幂

上面的代码发现当n的值稍微大一点就不行了,但是用高精度运算就不要有这种限制。下面是代码

代码语言:javascript
复制
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
long long int ans[100000];  //存放答案
long long int temp[100000];  //存放2的2^n的值
long long int save[100000];    //临时数组
int ans_len = 1;
int temp_len = 1;
void count_1(long long int* ans, long long int* temp)  //计算数组ans*数组temp,实际上就是简单的高精度大数相乘了
{ 

memset(save, 0, sizeof(save));
for (int i = 0; i < ans_len; i++)  //先不考虑进制
{ 

for (int j = 0; j < temp_len; j++)
{ 

save[i + j] += ans[i] * temp[j];
}
}
int weishu_max = ans_len + temp_len;   //最终答案最终这么多位数。可以那9999*9999这种极端证明
for (int i = 0; i < weishu_max; i++)
{ 

save[i + 1] += save[i] / 10;
save[i] %= 10;
}
if (save[weishu_max - 1] != 0)  //n位数*m位数要么就是m+n位数,要么就是m+n-1位数
ans_len = weishu_max;
else
{ 

ans_len = weishu_max - 1;
}
for (int i = 0; i < ans_len; i++)  //将save的复制给ans
ans[i] = save[i];
}
void count_2(long long int* temp)   //算2的2^n次方,也就是temp自乘
{ 

memset(save, 0, sizeof(save));
for (int i = 0; i < temp_len; i++)
for (int j = 0; j < temp_len; j++)
save[i + j] += temp[i] * temp[j];
int weishu_max = temp_len + temp_len;
for (int i = 0; i < weishu_max; i++)
{ 

save[i + 1] += save[i] / 10;
save[i] %= 10;
}
if (save[weishu_max - 1] != 0)
temp_len = weishu_max;
else
temp_len = weishu_max - 1;
for (int i = 0; i < temp_len; i++)
temp[i] = save[i];
}
int main()
{ 

int n;
cin >> n;
ans[0] = 1;
temp[0] = 2;
while (n > 0)
{ 

if (n % 2 == 1)
{ 

count_1(ans, temp);
}
n /= 2;
count_2(temp);
}
for (int i = ans_len-1; i >=0; i--)
{ 

cout << ans[i];
}
return 0;
}

如果用不考虑进制的做法话,实际上求大数还是有一定的限制,因为一个数组元素最多临时保存了n个数相加,如果当这n个数的和大于long long int的范围,那就会出错。那么可以用考虑进制的做法,虽然麻烦一点,但是会完美无缺,具体做法之前的博客都有提到,可以去看一看。实际上也非常简单,写个乘法竖式总结一下规律就可以写了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/215486.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月27日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 快速幂运算
  • 1.什么是快速幂
  • 2.快速幂的“小数”运算
  • 3.高精度(大数)的快速幂
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档