LL fast_Rec_Edition(LL a, LL b, LL m) {//快速幂 递归实现LL ans =1;if(b ==0)return1;if(b &1)return a *fast_Rec_Edition(a, b -1, m)% m;// 奇数,用位运算更快else{LL mul =fast_Rec_Edition(a, b /2, m);return mul * mul % m;//这一步一定不能写成//return fast_Rec_Edition(a, b / 2, m) * fast_Rec_Edition(a, b / 2, m);//这样会每次多次调用,使得复杂度回归O(b)}return ans; }
我们也可以进一步写出迭代版本的代码(From算法笔记):
迭代版:
LL fast_Iter_Edition(LL a, LL b, LL m) {//快速幂迭代实现LL ans =1;while(b){if(b &1)// 最低位是1ans = ans * a % m;a = a * a % m;// a², %m防止溢出b >>=1;// 右移}return ans; }
性能测试
#include usingnamespace std;typedeflonglong LL;//求 a^b % m 的几种写法及复杂度分析 LL normal_Edition(LL a, LL b, LL m) {//朴素版本LL ans =1;for(int i =0; i < b;++i)ans *= a;ans = ans % m;return ans; }LL advanced_Edition(LL a, LL b, LL m) {//普通优化LL ans =1;for(int i =0; i < b;++i)ans = ans * a % m;return ans; }LL fast_Rec_Edition(LL a, LL b, LL m) {//快速幂 递归实现LL ans =1;if(b ==0)return1;if(b &1)return a *fast_Rec_Edition(a, b -1, m)% m;else{LL mul =fast_Rec_Edition(a, b /2, m);return mul * mul % m;}return ans; }LL fast_Iter_Edition(LL a, LL b, LL m) {//快速幂迭代实现LL ans =1;while(b){if(b &1)ans = ans * a % m;a = a * a % m;b >>=1;}return ans; }intmain() {time_t start, over;LL a, b, m =7, ans;scanf("%lld %lld %lld",&a,&b,&m);//-----------------------------------------------------------------start =clock();ans =normal_Edition(a, b, m);over =clock();printf("使用朴素版, %lld^%lld %% %lld = %lld所用时间为 %f s\n", a, b, m, ans,(double)(over - start)/CLOCKS_PER_SEC);//-----------------------------------------------------------------start =clock();ans =advanced_Edition(a, b, m);over =clock();printf("使用优化版, %lld^%lld %% %lld = %lld所用时间为 %f s\n", a, b, m, ans,(double)(over - start)/CLOCKS_PER_SEC);//-----------------------------------------------------------------start =clock();ans =fast_Rec_Edition(a, b, m);over =clock();printf("使用快速幂递归版, %lld^%lld %% %lld = %lld所用时间为 %f s\n", a, b, m, ans,(double)(over - start)/CLOCKS_PER_SEC);//----------------------------------------------------------------- //-----------------------------------------------------------------start =clock();ans =fast_Iter_Edition(a, b, m);over =clock();printf("使用快速幂迭代版, %lld^%lld %% %lld = %lld所用时间为 %f s\n", a, b, m, ans,(double)(over - start)/CLOCKS_PER_SEC); //-----------------------------------------------------------------return0; }