题解 | #快速幂#
快速幂
https://www.nowcoder.com/practice/defdedf4fe984c6c91eefa6b00d5f4f0
#include<iostream> using namespace std; /* 3^10=3*3*3*3*3*3*3*3*3*3 //尽量想办法把指数变小来,这里的指数为10 3^10=(3*3)*(3*3)*(3*3)*(3*3)*(3*3) 3^10=(3*3)^5 3^10=9^5 //此时指数由10缩减一半变成了5,而底数变成了原来的平方,求3^10原本需要执行10次循环操作,求9^5却只需要执行5次循环操作,但是3^10却等于9^5,我们用一次(底数做平方操作)的操作减少了原本一半的循环量,特别是在幂特别大的时候效果非常好,例如2^10000=4^5000,底数只是做了一个小小的平方操作,而指数就从10000变成了5000,减少了5000次的循环操作。 //现在我们的问题是如何把指数5变成原来的一半,5是一个奇数,5的一半是2.5,但是我们知道,指数不能为小数,因此我们不能这么简单粗暴的直接执行5/2,然而,这里还有另一种方法能表示9^5 9^5=(9^4)*(9^1) //此时我们抽出了一个底数的一次方,这里即为9^1,这个9^1我们先单独移出来,剩下的9^4又能够在执行“缩指数”操作了,把指数缩小一半,底数执行平方操作 9^5=(81^2)*(9^1) //把指数缩小一半,底数执行平方操作 9^5=(6561^1)*(9^1) //此时,我们发现指数又变成了一个奇数1,按照上面对指数为奇数的操作方法,应该抽出了一个底数的一次方,这里即为6561^1,这个6561^1我们先单独移出来,但是此时指数却变成了0,也就意味着我们无法再进行“缩指数”操作了。 9^5=(6561^0)*(9^1)*(6561^1)=1*(9^1)*(6561^1)=(9^1)*(6561^1)=9*6561=59049 我们能够发现,最后的结果是9*6561,而9是怎么产生的?是不是当指数为奇数5时,此时底数为9。那6561又是怎么产生的呢?是不是当指数为奇数1时,此时的底数为6561。所以我们能发现一个规律:最后求出的幂结果实际上就是在变化过程中所有当指数为奇数时底数的乘积。 ———————————————— 版权声明:本文为CSDN博主「刘扬俊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_19782019/article/details/85621386 */ // 快速幂的思想是不断的把指数减半(对半) // 另外,(a * b) % p = (a % p * b % p) % p 为默认知识 long long int FastPower(long long base, long long power, long long int mod){ long long int result = 1; while(power > 0){ if(power%2 == 0){ // 当power为偶数时,直接除2,底数相乘 power = power / 2; base = base * base % mod; } else{ // 当power为奇数时,先减一让其成为偶数,代价是把这时的底数拿出来 power = power - 1; result = result * base % mod; // 拿出来保存,这里相当于把所有的奇数对应的底数都乘起来并保存结果 power = power / 2; base = base * base % mod; } } return result; } int main(){ int OperationTimes = 0; cin >> OperationTimes; for(int i = 0; i < OperationTimes; i++){ long long int base_a = 0; long long int power_b = 0; long long int mod_p = 0; cin >> base_a >> power_b >> mod_p; cout << FastPower(base_a, power_b, mod_p) << endl; } return 0; }#解题自我记录#