可以通过动态编程解决这个问题吗?

时间:2014-12-11 11:43:01

标签: algorithm dynamic-programming

鉴于 n,m,d 。答案存储在以下代码中的 sum 变量中:

int x = m / d;
int sum = 0;
for (int i = 1; i <= x; i++) {
    sum += mobius(i) * ((x / i) ^ n);
}

现在问题是当 d [l,r] 不同时,找到总和%(10 ^ 9 + 7)如上所述, n,m 。我只能通过暴力来做到这一点,但约束是 1&lt; = n,m,l,r&lt; = 10 ^ 7 。所以蛮力解决方案无法超越时限。 是否存在一些潜在的重叠子问题和最佳子结构属性,可用于通过动态规划解决问题?

链接:Mobius Function,我已经预先计算了 O(nlogn)中的mobius功能。
编辑:鉴于 t,n,m 。其中 t 是测试用例的数量,
l,r 被赋予 t 次。我们必须输出如上所述的总和。

示例输入:
T:2
N:3,M:10
l r 的值 9 9
10 10

样品输出:
1
1

1 个答案:

答案 0 :(得分:2)

请注意,当您将m除以d来计算x时,x只会有大约2*sqrt(m)个唯一值。

这意味着您只需要为x的每个唯一值触发第二个循环。

同样,在x/i的计算中,2*sqrt(x)只有大约(x/i)个唯一值。这意味着您只需为每个唯一值计算(x/i)^n

对于x/i的每个唯一值,将有一系列i值产生此值。

然后,您需要为生成相同输出的i的所有值加起来mobius[i]。这可以通过准备一个具有Mobius函数累积和的数组来实现(这个累积和称为Mertens function)。

例如,如果

M[k] = sum[ Mobius(i) for i = 1..k ]

然后

sum[ Mobius(i) for i = low..high ] = M[high] - M[low-1]

整体而言,复杂性为O( sqrt(n) * sqrt(n) ) = O(n)(除了计算Mobius功能所花费的时间外)。