python - 快速访问成对操作的总和

标签 python algorithm data-structures

给定一个数字向量 v ,我可以通过使用累积和来访问这个向量的部分的总和,即,而不是 O(n)

v = [1,2,3,4,5]
def sum_v(i,j):
    return sum(v[i:j])
我可以做 O(1)
import itertools
v = [1,2,3,4,5]
cache = [0]+list(itertools.accumulate(v))
def sum_v(i,j):
    return cache[j] - cache[i]
现在,我需要类似的东西,但对于 pairwise而不是 sum_v :
def pairwise(i,j):
    ret = 0
    for p in range(i,j):
        for q in range(p+1,j):
            ret += f(v(p),v(q))
    return ret
哪里f最好是相对任意的东西(例如,*^ 或...)。但是,仅适用于产品或仅适用于 XOR 的东西也很好。
PS1 .我正在寻求加速 O , 不通用 memoization functools.cache .
PS2 .问题是关于算法,而不是实现,因此与语言无关。我标记了它 python只是因为我的例子是在 python 中的。
PS3 .显然,可以预先计算 pairwise 的所有值。 ,所以解应该是 o(n^2)在时间和空间上(最好是线性的)。

最佳答案

对于二元运算,例如 or, and, xor , O(N)算法是可能的。
让我们在这个例子中考虑 XOR,但这也可以很容易地修改为 OR/AND。
这里要注意的最重要的事情是,位 x 上的二元运算符的结果。两个数字的结果不会影响位 y 的结果. (您可以通过尝试类似 010 ^ 011 = 001 之类的方法轻松看到这一点。因此,我们首先计算所有数字的最左边位对最终总和的贡献,然后是下一个最低有效位,依此类推。这是一个简单的算法/伪代码为了那个原因:

  • 构造一个简单的表 dp ,其中 dp[i][j] = count of numbers in range [i,n) with jth bit set
  • l = [5,3,1,7,8]
    n = len(l)
    ans = 0
    
    max_binary_length = max(log2(i) for i in l)+1  #maximum number of bits we need to check
    
    for j in range(max_binary_length):
        # we check the jth bits of all numbers here
        for i in range(0,n):
            # we need sum((l[i]^l[j]) for j in range (i+1,n))
            current = l[i]
            if jth bit of current == 0:
                # since 0^1 = 1, we need count of numbers with jth bit 1
                count = dp[i+1][j]
            else:
                # we need count of numbers with jth bit 0
                count = (n-i)-dp[i+1][j] 
                # the indexing could be slightly off, you can check that once
            ans += count * (2^j)
            # since we're checking the jth bit, it will have a value of 2^j when set
    print(ans)
    
    在大多数情况下,对于整数,位数 <= 32。所以这应该具有 O(N*log2(max(A[i]))) 的复杂度== O(N*32) == O(N) .

    关于python - 快速访问成对操作的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66112879/

    相关文章:

    android - 如何下载适用于安卓的谷歌源代码

    python - 如何将列表列表中的所有数字变成整数

    python - 将 QWebEngine 连接到代理

    java - 使用 DFS 生成迷宫失败,我不知道为什么

    algorithm - 具有循环依赖的 DFS

    algorithm - 存储一百万个值的最佳数据结构?

    java - 只处理其中一个子树

    python - 导致属性错误: 'classObject' object has no attribute '_w' ?的原因

    search - 如何在有序集合中找到元素的索引?

    algorithm - 在线性时间内找到树中每个节点的最左边的子节点?