矩阵乘法中最大运算的模运算

时间:2017-08-19 07:15:24

标签: c++ math

我有一个函数可以找到范围的最大值:

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之外的任何解决方案)?

1 个答案:

答案 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值保留在结构或其他内容中。