杭電oj人見人愛A^B
阿新 • • 發佈:2021-01-16
技術標籤:oj
杭電oj人見人愛A^B
最先想到的就是pow()函式,但是在測試過程中發現pow()函式對輸入的資料有諸多限制,可能導致錯誤的情況:
1.如果底數 x 為負數並且指數 y 不是整數,將會導致 domain error 錯誤。
2.如果底數 x 和指數 y 都是 0,可能會導致 domain error 錯誤,也可能沒有;這跟庫的實現有關。
3.如果底數 x 是 0,指數 y 是負數,可能會導致 domain error 或 pole error 錯誤,也可能沒有;這跟庫的實現有關。
4.如果返回值 ret 太大或者太小,將會導致 range error 錯誤。
解決方案:同餘方程&快速冪取模演算法
因要求輸出最後三位數字,故在運算時,只取最後三位數字進行運算。
#include<iostream>
using namespace std;
int main()
{
int m,n,r;
while(cin>>m>>n&&(n||m))
{
r=1;
m%=1000;
for(int i=1;i<=n;i++)
r=r*m%1000;
cout<<r<<endl;
}
return 0;
}
快速冪取模演算法:
1.模運算與乘法的性質
乘積取模可以在乘之前先取模
x * y % d = ((x % d) * (y % d)) % d;
比如:a*a%c = ((a % c) * ( a % c)) % c;
2.本題公式
當b為偶數時:ab mod c = ((a2)b/2) mod c
當b為奇數時:ab mod c = ((a2)b/2× a) mod c
因此快速冪實際是分治演算法,每次將b分一半,直到b=0;):
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<iomanip>
#include<algorithm>
using namespace std;
typedef long long ll;
ll quick_mod(ll m,ll n,ll k)
{
if(n==0) return 1;
if(n%2==1)
return m*quick_mod(m,n-1,k)%k;
else
{
ll num=quick_mod(m,n/2,k);
return num*num%k;
}
}
int main()
{
ll a,b,c;
c=1000;
while(cin>>a>>b)
{
ll base=quick_mod(a,b,c);
cout<<base<<endl;
}
return 0;
}