快速冪和快速乘


題目    a^b  多組輸入a,b   求a^b的個位數

快速冪:

#include<stdio.h>
int ksm(long long a,long long b,long long c) { int ans=1; while(b) { if(b&1) { ans=(ans*a)%c; } a=(a*a)%c; b=b/2; } return ans; } int main() { long long n,m; while(~scanf("%lld %lld",&n,&m)) printf("%lld\n",ksm(n,m,10)); return 0; } 

當a,b很大的時候 在10^9時,用常規的方法就容易超時

所以就優化

首先n^x * x^y = n^(x+y),這個是顯然的吧……
那么由此可以推出
n^m = n^x1 * n^x2 * ... * n^xi ,其中 x1 + x2 + ... + xi = m
那么,我們應該找到一種最優的方式把m分解,然后用可以很容易計算出來的n^x值相乘,就可以得到n^m的答案。
什么樣的n^x算起來最快呢?
x = 1 , n^x = n
x = 2 , n^x = n^2
x = 4 , n^x = n^4 = (n^2)^2
x = 8 , n^x = n^8 = (n^4)^2
....
然后,我們知道任何一個數都可以輕松用1,2,4,8,16...的和表示出來,即,把這個數轉為二進制即可。
那么對於任意一個n^m,我們就可以在O(log m)的時間內完成了。
For example: 求2^13
2^13 = 2^1 * 2^4 * 2^8
就可以了……
 
 
快速乘
#include<stdio.h>
long long ksm(long long,long long,long long); long long ksc(long long,long long,long long); int main() { long long n,m; while(~scanf("%lld%lld",&n,&m)) printf("%lld\n",ksm(n,m,10)); return 0; } long long ksm(long long a,long long b,long long c) { long long ans=1; while(b) { if(b%2) ans=ksc(ans,a,10)%c; a=(a*a)%c; b/=2; } return ans; } long long ksc(long long a,long long b,long long c) { long long ans=0; while(b) { if(b%2) ans=(ans+a)%c; a=(a+a)%c; b/=2; } return ans; }

當a,b<=10^18時   快速冪也不能解決了  所以引入快速乘

沿用之前的方法,但是注意這里的模數是10^18
之前10^9*10^9 long long 可以存下

考慮到冪次可以轉換成連續乘
連續乘可以轉換成連續加
a^4 = a*a*a*a
a*a =(a+a+a.....a)
注意到兩個10^18的數相加是可以的
同樣我們得到一個快速乘

比如計算出a,2a,4a,8a,16a
每次乘二,不會爆

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM