我有一个函数可以找到范围的最大值:
A,B,C是2 d矩阵
void solve()
{
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
C[i][j] = 0;
for (k = 0; k < n; k++)
{
C[i][j] = max(C[i][j],A[i][k]*B[k][j]);
//C[i][j] can become very large if solve() is called multiple times
}
}
}
for(int i = 0;i<n;i++)
{
for(int j=0;j<n;j++)
{
A[i][j] = C[i][j];
}
}
}
solve()方法可以被调用很多次(10 ^ 7)
A [i] [j],B [i] [j],C [i] [j]可以是10 ^ 9.
n将很小(大约20)。
我需要用模m打印最终矩阵C(即C [i] [j]%m)
由于我们无法对中间结果应用mod(它可能会产生错误的结果)。
问题是整数溢出,因为它可以跨越int和long的最大值。
解决这个问题的任何建议(除了big int之外的任何解决方案)?
答案 0 :(得分:1)
由于这是竞争性节目,你应该开箱即用。由于您需要计算实际最大值而不是模数的最大值,因此在处理时不能使用模数。但是:
你只是做乘法,你不担心实际值,而是不同结果之间的比较(知道哪个更大)。你可以使用同构。也就是说,计算数字和中间结果的log()并将模数保持为辅助信息。你可以这样做,因为 b&lt; c d&lt; =&gt; log(a b)&lt; log(c d)&lt; =&gt; log(a)+ log(b)&lt; log(c)+ log(d)。所以现在你只需要在数字之间做补充,价值将保持很小。你会失去一些精确度,但考虑到背景,这应该没问题。问题是您将无法从日志中重建模数,因此您应该将mod值保留在结构或其他内容中。