杭电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;
}