我所问的不是this very popular question的副本。对于随机选择的输入,可以进行一些快速测试,如果他们不能说“不是正方形”,则必须进行平方根的一些计算(我自己也尝试了solution)。
当要测试的数字来自简单序列时,情况会有所不同,因为可以使用先前的(近似)平方根。对于一个简单的序列,它也是微不足道的,例如,
long sqrt = 1;
for (long i=1; i<limit; ++i) {
if (sqrt*sqrt == i) {
handleSquare(i);
++sqrt;
}
}
我的问题是如何为更复杂的序列做些什么,比如
x[i] = start + i*i;
或
x[i] = start - i*i*i;
我正在考虑牛顿的方法,但我看不出如何快速实现(因为除法是一项非常昂贵的操作)。
答案 0 :(得分:0)
您希望将哪种序列应用于算法?下面是一个解决方案,当x [i]发散但不会太快时应该可以正常工作。
例如
x[i] = a*i^p + o(i^p)
而且我足够大你会有
x[i+1]-x[i] ~ p * a * i^{p-1}.
如果y [i]表示最大的整数,那么
y[i]^2 <= x[i]
然后你有
y[i] ~ sqrt(a) i^{p/2}
和
y[i+1]-y[i] ~ 1/(2 y[i]) * (x[i+1]-x[i]) ~ p/2 * sqrt(a) i^{p/2-1}
所以你可以把它当作y [i + 1]的猜测,然后更新到正确的值,这可以节省你一些迭代。
通常,您始终可以使用公式
y[i+1]-y[i] ~ 1/(2 y[i]) * (x[i+1]-x[i])
作为猜测但这仅在x [i + 1] -x [i]相对于y [i] ^ 2小时 - 即相对于x [i]时才有用。使用(精确)二阶扩展
对公式进行一点改进也是值得的y[i+1]^2 = y[i]^2 + 2y[i](y[i+1]-y[i]) + (y[i+1]-y[i])^2
为了改善y [i + 1]的猜测。
请注意,如果当i很大或者x指数快速偏离时x [i]仍然有界,这将无法正常工作。