问题链接 - http://www.spoj.com/problems/LASTDIG/
摘要 - 给定2个非负整数a和b,打印a ^ b的最后一位。
我尝试使用算法使用更少的内存空间(http://en.wikipedia.org/wiki/Modular_exponentiation#Memory-efficient_method)来查找模幂运算,但我的解决方案出现了TLE(超出时间限制)错误。我应该在1秒内完成运行代码的更改?请注意,10个测试用例需要在1秒内运行。
我的解决方案:
#include<iostream>
#include<vector>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
typedef long long LL;
using namespace std;
int ME(LL A, LL B)
{
LL c=1;
int E=0;
while(E<B)
{
c=(c*A)%10;
E++;
}
return c;
}
int main()
{
int t;
LL a, b;
vector <int> lDigit(31);
cin>>t;
for(int i=0;i<t;i++)
{
cin>>a>>b;
if(b>=99999)
lDigit[i]=ME(a, b);
else
{
int temp=pow(a, b);
lDigit[i]=temp%10;
}
}
for(int i=0;i<t;i++)
cout<<lDigit[i]<<endl;
return 0;
}
答案 0 :(得分:0)
您正在使用的算法对于大取幂而言会很慢。快速模幂运算考虑指数中的位,并且只需要O(lg(n))乘法/除法,而您的代码需要O(n)次乘法。在10亿的指数下,差异大约为10亿到30。请参阅Right-to-left binary method。
来自维基百科的伪代码是
function modular_pow(base, exponent, modulus)
Assert :: (modulus - 1) * (base mod modulus) does not overflow base
result := 1
base := base mod modulus
while exponent > 0
if (exponent mod 2 == 1):
result := (result * base) mod modulus
exponent := exponent >> 1
base := (base * base) mod modulus
return result
在C中成为
int modular_pow(int base, int exponent, int modulus) {
int result = 1;
base = base % modulus;
while (exponent) {
if (exponent & 1) {
result = (result * base) % modulus;
}
exponent >>= 1;
base = base * base % modulus;
}
return result;
}
虽然你的代码为20亿次指数运行while循环20亿次,但上面的代码运行循环~32次。