题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2035
题解:
本题可以应用快速幂求解,时间复杂度 O(log n),而用普通循环求解,复杂度 O(n)
代码一:快速幂求解
代码二:普通方法求解,每次只需用后三位去计算即可,因此每次循环的=得到的结果对1000取模,即得到后三位
快速幂介绍:
首先,快速幂的目的就是做到快速求幂,假设我们要求a^b,按照朴素算法就是把a连乘b次,这样一来时间复杂度是O(b)也即是O(n)级别,快速幂能做到O(logn),快了好多好多。
假设我们要求a^b,那么其实b是可以拆成二进制的,该二进制数第i位的权为2^(i-1),例如当b==11时
a11=a(2^0+2^1+2^3)
11的二进制是1011,11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1,因此,我们将a¹¹转化为算 a2^0*a2^1*a2^3,也就是a1*a2*a8 ,原来算11次,现在只算三次。
由于是二进制,很自然地想到用位运算这个强大的工具:&和>>
&运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位。还可以判断奇偶x&1==0为偶,x&1==1为奇。
快速幂模板:https://blog.csdn.net/gzu_zb/article/details/89959534
AC代码:
代码一:
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll mod_pow(ll x, ll n, ll mod){
ll res = 1;
while( n > 0 ){
if( n & 1 ) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
int main() {
int m, n;
while (cin >> m >> n && m + n) {
cout << mod_pow(m, n, 1000) << endl;
}
return 0;
}
代码二:
#include <iostream>
using namespace std;
int main() {
int m, n;
while (cin >> m >> n && m + n) {
int ans = 1;
for(int i = 0; i < n; i++){
ans *= m;
ans %= 1000;
}
cout << ans <<endl;
}
return 0;
}
附:快速幂练习题:https://blog.csdn.net/gzu_zb/article/details/90238344