高维前缀和

一、概述

高维前缀和是一种解决多维度数据求和问题的算法,可以用于统计图像、地图等场景中的像素值、区域和等问题。该算法首次出现在1986年James Abello和Jeffrey S. Vitter两人的论文《Random Sampling from Multidimensional Distributions》中。基本思想是将每个维度的前缀和预处理出来,然后通过简单的计算获取任意矩形区域的和。

二、二维前缀和

首先,我们从二维前缀和开始介绍,以方便更好地理解高维前缀和。二维前缀和可以用于求解矩阵中某个矩形区域的和。定义矩阵 $M$ 的前缀和 $S$ 为:

S[i][j] = M[1][1] + M[1][2] + ... + M[1][j]
         + M[2][1] + M[2][2] + ... + M[2][j]
         + ...
         + M[i][1] + M[i][2] + ... + M[i][j]

显然,$S[i][j]$ 表示矩阵 $M$ 左上角到 $(i,j)$ 位置的所有元素之和。

求解任意矩形区域的和时,可以利用前缀和进行快速计算。假设要求解矩形 $(x1,y1)$ 到 $(x2,y2)$ 中所有元素的和,即 $\sum_{i=x1}^{x2}\sum_{j=y1}^{y2}M[i][j]$。通过前缀和,可以得到下面的计算公式:

sum = S[x2][y2] - S[x2][y1-1] - S[x1-1][y2] + S[x1-1][y1-1]

通过该公式,可以用 $O(1)$ 的时间复杂度求解任意矩形区域的和。

三、高维前缀和

对于 $n$ 维的数组而言,可以使用类似二维前缀和的方式进行求解。定义 $n$ 维数组 $A$ 的前缀和为:

S[p1][p2]...[pn] = A[1][1]...[1][p1][1]...[1][p2]...[1][pn]
                  + A[1][1]...[1][p1][1]...[1][p2]...[2][pn]
                  + ...
                  + A[1][1]...[1][p1][2]...[m1][1]...[1][pn]
                  + ...
                  + A[1][n]...[m1][n][p1][1]...[1][p2]...[1][pn]
                  + ...
                  + A[m1][1]...[m1][n][p1][1]...[1][p2]...[1][pn]
                  + ...
                  + A[m1][m2]...[m_n][p1][1]...[1][p2]...[1][pn]

其中,$m_i$ 表示第 $i$ 维的长度,$p_i$ 表示在第 $i$ 维中要求和的最大下标。

类比二维前缀和,对于 $n$ 维数组 $A$,为了快速地计算任意多维矩形区域的和,可以预处理出 $n$ 维前缀和数组 $S$。对于 $n$ 维矩形区域 $R$,可以使用下面的公式进行计算:

sum = S[p1][p2]...[pn] - S[p1][p2]...[q_n-1][pn] - ... - S[p1][q_2-1]...[q_n-1][pn] + S[p1][q_2-1]...[q_n-1][q_n-1]
    - S[q_1-1][p2]...[q_n-1][pn] + S[q_1-1][q_2-1]...[q_n-1][pn] + ... + S[q_1-1][q_2-1]...[q_n-1][q_n-1] 

其中,$p_i$ 表示在第 $i$ 维中要求和的最大下标,$q_i$ 表示在第 $i$ 维中要求和的最小下标。

四、代码示例

下面是使用 C++ 实现的二维前缀和和高维前缀和的代码示例。

二维前缀和:

int n, m;
int a[MAX_N][MAX_M];
int s[MAX_N][MAX_M];

void precompute2D() {
    // 计算前缀和
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            s[i][j] = s[i][j-1] + s[i-1][j] - s[i-1][j-1] + a[i][j];
        }
    }
}

int query2D(int x1, int y1, int x2, int y2) {
    return s[x2][y2] - s[x2][y1-1] - s[x1-1][y2] + s[x1-1][y1-1];
}

高维前缀和:

const int MAX_D = 10;
const int MAX_SIZE = 1 << MAX_D;
int n, m;
int d[MAX_D]; // 每维的大小
int a[MAX_SIZE][MAX_SIZE][MAX_D];
int s[MAX_SIZE][MAX_SIZE][MAX_D];

void precomputeND() {
    // 计算前缀和
    for (int k = 0; k < MAX_D; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                s[i][j][k] = s[i][j-1][k] + s[i-1][j][k] - s[i-1][j-1][k] + a[i][j][k];
            }
        }
    }
}

int queryND(int *p, int *q) {
    int sum = 0;
    for (int k = 0; k < MAX_D; k++) {
        int p1 = p[k]+1, q1 = q[k];
        for (int i = k+1; i < MAX_D; i++) {
            p1 *= d[i];
            q1 *= d[i];
        }
        int p2 = 1, q2 = 0;
        for (int i = 0; i < k; i++) {
            p2 *= d[i];
            q2 *= d[i];
        }
        sum += s[q1][q2][k] - s[q1][p2-1][k] - s[p1-1][q2][k] + s[p1-1][p2-1][k];    
    }
    return sum;
}

原创文章,作者:SCIOC,如若转载,请注明出处:https://www.506064.com/n/349494.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
SCIOCSCIOC
上一篇 2025-02-15 17:10
下一篇 2025-02-15 17:10

相关推荐

  • mgrid:一个全方位的高维数据分析工具

    一、简介 mgrid是一个基于Python的高维数据分析工具,其主要作用是简化高维数据的可视化和分析过程。mgrid通过对数据进行降维和多维数据可视化,帮助用户更好地理解数据,发现…

    编程 2025-01-09
  • Python startwith函数:字符串前缀匹配

    Python是一种高级编程语言,广泛应用于各种应用开发领域。字符串操作是编程中常用的操作之一,Python为我们提供了许多字符串操作的函数,其中之一就是`startwith()`函…

    编程 2024-12-27
  • 如何通过模糊查询实现快速寻找redis中的key前缀

    一、什么是Redis Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库,常用作缓存、消息队列和排行榜等。 二、Redis中的Key Re…

    编程 2024-12-22
  • prefixsuffix:前缀和后缀的魔法

    作为一个编程开发工程师,当涉及到字符串操作时,我们经常使用到前缀和后缀的技巧。本文将从多个方面详细探讨prefixsuffix的应用,包括它的定义、用法、复杂度以及代码示例。 一、…

    编程 2024-12-16
  • 使用php自动添加css前缀(PHP后缀)

    本文目录一览: 1、php语句加CSS 2、在php文件里如何引入css文件? 3、php中怎么连接外部css样式表? 4、在PHP里怎么添加CSS和JS文件 5、系统会自动给cs…

    编程 2024-12-15
  • 探究Python中的b前缀

    引言: Python编程语言作为一门解释型语言,其特殊之处即为其用法方便简单。而Python中的b前缀是其中的一个非常有用的元素,作者在使用Python编写程序时感触颇深,故而深入…

    编程 2024-12-13
  • Python字符串前缀详解

    Python是一门高级编程语言,字符串是Python中最基本的数据类型之一。而字符串前缀是字符串的一种特殊形式,它可以让程序员更加方便地操作字符串。本文将从多个方面详细阐述Pyth…

    编程 2024-11-25
  • noprefixroute:对无前缀路由的详细阐述

    无前缀路由是Web开发中常见的路由方案之一,其核心思想是,在URL中省略掉某些较为固定的前缀,使得URL更加简洁易读、方便操作。在接下来的文章中,我们将从多个方面对noprefix…

    编程 2024-11-22
  • python一键修改ios前缀(ios怎么修改后缀)

    本文目录一览: 1、如何用python写ios的游戏脚本? 2、怎么使用python编写一个能把列表内所有元素前面都加一个字符的函数 3、苹果的python怎么升级 4、用pyth…

    编程 2024-11-12
  • 详解阿里云前缀

    阿里云是目前业内知名的云计算服务提供商,其中涉及到的阿里云前缀在使用阿里云盘时非常重要,本文将从多个方面详细解释阿里云前缀的相关内容。 一、阿里云前缀盘 阿里云前缀盘是阿里云云盘新…

    编程 2024-10-08

发表回复

登录后才能评论