我们得到(x,y)形式的 N 点,我们需要计算以下函数:
我正在寻找O(N log N)
解决方案。
我最初的想法是用X对点进行排序,然后使用BIT,但我无法制定明确的解决方案。
答案 0 :(得分:1)
我有一个使用O(N log(M))
时间和O(M)
内存的解决方案,其中M
是Y
范围的大小。它与您的想法类似。
首先对点进行排序,以使X
坐标正在增加。
让我们为所有对A
写(X[i] - X[j]) * (Y[i] - Y[j])
的总和i > j
,Y[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}}记忆,那么这应该可以正常工作。