2 回答
TA贡献1820条经验 获得超9个赞
我是否只是在正常计算完公式后修改p?
不。首先,您必须计算模的乘法逆。这是有效实施的棘手部分。其余的确实只是乘法和求和模。x[m] - x[j]
p
p
请记住,浮点运算不能在有限域中工作。那里的一切都是精确的整数。
PS:为了解决有关除法的问题,这就是除法在有限领域中的工作方式:
y/x
实际上哪里是 的乘法逆,即 。例如,让我们使用 7 表示 。比方 2 的乘法逆比是 4:。这意味着 ,即 。y * z
z
x
x * z = 1 mod p
p
2 * 4 == 8 (== 1 mod 7)
3/2 mod 7
3 * 4 mod 7
5
TA贡献1775条经验 获得超8个赞
您应该记住,在将两个数字相乘后,始终要对结果进行取模。 如果 为,则可能导致整型溢出。如果较大(如),则可简单地导致溢出。对于这种情况,在将两个数字和 相乘之前,您应该将它们转换为并将结果取模,最后将其转换回。a*b*ca<p,b<p,c<pp=183269p998244353a*babint64pint
这里的另一点:并不总是等价于当模。实际上,在大多数情况下,这是错误的。您应该改用。a-apa = (a % p + p) % p
以下是可以产生正确结果的修改代码(我刚刚学习了这个问题的golang,所以请原谅我可能的不当代码):
reconstructed := 0
for _, k := range x_input {
y := points[k]
pr_x := 1
for _, l := range x_input {
if l != k {
inv := mod_inverse(l - k, p)
// You forgot to multiply pr_x by l
// pr_x *= inv
pr_x = pr_x * inv % p * l % p
}
}
y = y * pr_x % p
reconstructed += y
}
return reconstructed % p
func mod_inverse(a, p int) int {
if a < 0 { // negative numbers are not allowed
// The following line is wrong! (a % p) == (a % p + p) % p when a < 0, but not -a
// a = a * -1
a = ((a % p) + p) % p
}
for i := 1; i < p; i++ {
if ((a % p) * (i % p)) % p == 1 {
return i
}
}
// I suspect whether you should report an error here instead of returning p
return p
}
顺便说一句,的时间复杂度是 ,在大多数情况下可能是低效的。您可以使用扩展欧几里得算法来计算时间上模的乘法逆。此外,模的乘法逆值只是当是素数时,你可以使用平方的幂快速计算。这两种方法都很复杂,但后一种方法更容易实现。mod_inverseO(p)xpO(log p)xp(x^(p-2)) % ppO(log p)
对不起我的英语不好。随时指出我的拼写错误和错误。
- 2 回答
- 0 关注
- 99 浏览
添加回答
举报