chinpom 写道
LZ那样求幂a^b结果的最后三位数的话,就算是long型都会很快越界的。比如 20^15 就已经超过64位有符号的最大long值了,而且大量的乘法的效率低。原问题的形式可以用 x^y mod N 来表示,这在RSA加密算法中是属于基础的准备算法,可以这样来求:
Java代码
public class PowerQuestion {
public static int modeXp(int x, int y, int n) {
if (y == 0) return 1;
int z = modeXp(x, y >> 1, n); //把y除以2并取整
if ((y & 1) == 0) { //如果y为偶数
return (z * z) % n;
} else {
return (x * z * z) % n;
}
}
public static void main(String[] args) {
System.out.println(modeXp(9, 9, 1000));
}
}
public class PowerQuestion {
public static int modeXp(int x, int y, int n) {
if (y == 0) return 1;
int z = modeXp(x, y >> 1, n); //把y除以2并取整
if ((y & 1) == 0) { //如果y为偶数
return (z * z) % n;
} else {
return (x * z * z) % n;
}
}
public static void main(String[] args) {
System.out.println(modeXp(9, 9, 1000));
}
} 假设N为 x,y,n 三个数中最长的二进制位数,则算法的时间复杂度为O(N^3)。
lz的解法不会越界的吧 - -# 可以优化倒是肯定的
Java代码
public static int foo(int a, int b) {
a = a % 1000;
int res = a;
int i = 1;
for (; i * 2 < b; i *= 2) {
res *= res;
res %= 1000;
}
for (; i < b; i++) {
res *= a;
res %= 1000;
}
return res;
}
public static int foo(int a, int b) {
a = a % 1000;
int res = a;
int i = 1;
for (; i * 2 < b; i *= 2) {
res *= res;
res %= 1000;
}
for (; i < b; i++) {
res *= a;
res %= 1000;
}
return res;
}
|