计算函数求和的有效算法

时间:2015-07-21 10:50:38

标签: algorithm math data-structures time-complexity

我们得到(x,y)形式的 N 点,我们需要计算以下函数:

F(i,j)=(| X [i] - X [j] |)*(| Y [i] - Y [j] |)

所有有序对(i,j)

的F(i,j)的计算求和

N <= 300000

我正在寻找O(N log N)解决方案。

我最初的想法是用X对点进行排序,然后使用BIT,但我无法制定明确的解决方案。

1 个答案:

答案 0 :(得分:1)

我有一个使用O(N log(M))时间和O(M)内存的解决方案,其中MY范围的大小。它与您的想法类似。

首先对点进行排序,以使X坐标正在增加。

让我们为所有对A(X[i] - X[j]) * (Y[i] - Y[j])的总和i > jY[i] > Y[j]B为所有对的总和i > j成对Y[i] < Y[j],以A + B

总和O(N)可以在A - B时间内轻松计算,最终答案可以从A计算得出。因此,计算[a, b)就足够了。

现在创建一个二进制索引树,其节点由b = a + 2^k格式的间隔索引,k用于某些[Y_min, Y_max]。 (不是很好的传导,但是你知道我的意思,对吧?)根节点应该覆盖Y的可能值的间隔[a, b)

对于i和任何f(a, b, i)索引的任何节点,请f(a, b, i)(X, Y) = sum of (X - X[j]) * (Y - Y[j]) for all j such that j < i and Y[j] < Y为以下多项式:

P * XY + Q * X + R * Y + S

它的格式为P, Q, R, S,因此这样的多项式可以用四个数字i = 0表示。

现在从f(a, b, i)(X[i], Y[i])开始,您可以计算i。要从i + 1转到[a, b),您只需要更新包含Y[i]的那些间隔i = N。当您到达A时,会计算O(M)的值。

如果你能负担{{1}}记忆,那么这应该可以正常工作。