首页 > 其他分享 >前缀和

前缀和

时间:2023-11-22 17:26:10浏览次数:32  
标签:x1 前缀 sum x2 y1 y2

前缀和

1.前缀和简介

前缀和是指某序列的前n项和,可以把它理解为数学上的数列的前n项和,(而差分可以看成前缀和的逆运算).合理的使用前缀和与差分,可以将某些复杂的问题简单化。

2.前缀和好处

求数组的某个区间的和时,最容易想出暴力算法,遍历区间求和,时间复杂度为O(n * m)

而使用前缀和进行求和的话,时间复杂度降到O(n + m)

3. 一维前缀和

首先做一个预处理,定义一个sum[]数组,sum[i]代表a数组中前i个数的和。

const int N = 10000;
int sum[N], a[N]; //sum[i]=a[1]+a[2]+a[3].....a[i];
void qianzuihe (){
    for (int i = 1; i < N;i++){
        sum[i] = sum[i - 1] + a[i];
    }
}



cin >> l >> r;
cout << sum[r] - sum[l - 1] << endl;//对数组区间[l,r]求和,时间复杂度为O(1)
  • 原理

    sum[r] = a[1] + a[2] + a[3] + a[l-1] + a[l] + a[l + 1] ...... a[r];
    sum[l - 1] = a[1] + a[2] + a[3] + a[l - 1];
    sum[r] - sum[l - 1] = a[l] + a[l + 1] + ......+ a[r];

4.二维前缀和

输入一个n行m列的整数矩阵,再输入q个询问,每个询问包含四个整数x1, y1, x2, y2,表示一个子矩阵的左上角坐标和右下角坐标。对于每个询问输出子矩阵中所有数的和。

同一维前缀和一样,我们先来定义一个二维数组s[] [] , s[i] [j] 表示二维数组中,左上角(1, 1)到右下角(i, j)所包围的矩阵元素的和。接下来推导二维前缀和的公式。

  • 求s[i] [j]前缀和数组(预处理)

紫色面积是指(1, 1)左上角到(i, j - 1)右下角的矩形面积, 绿色面积是指(1, 1)左上角到(i - 1, j )右下角的矩形面积。每一个颜色的矩形面积都代表了它所包围元素的和。

从图中我们很容易看出,整个外围蓝色矩形面积s[i][j] = 绿色面积s[i - 1][j] + 紫色面积s[i][j - 1] - 重复加的红色的面积s[i - 1][j - 1] + 小方块的面积a[i][j];

因此得出二维前缀和预处理公式

s[i][j] = s[i - 1][j] + s[i][j - 1 ] + a[i] [j] - s[i - 1][j - 1]
const int N = 10000;
int sum[N][N], a[N][N]; //sum[i]=a[1]+a[2]+a[3].....a[i];
void qianzuihe (){
    for (int i = 0; i < N;i++){
        for (int j = 0; j < N;j++){
            sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];
        }
    }
}
  • 求求以(x1,y1)为左上角和以(x2,y2)为右下角的矩阵的元素的和

紫色面积是指 (1, 1)左上角到(x1 - 1, y2)右下角的矩形面积 ,黄色面积是指(1, 1)左上角到(x2, y1 - 1)右下角的矩形面积;

绿色矩形的面积 = 整个外围面积s[x2, y2] - 黄色面积s[x2, y1 - 1] - 紫色面积s[x1 - 1, y2] + 重复减去的红色面积 s[x1 - 1, y1 - 1]

因此二维前缀和的结论为:

(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
s[x2, y2] - s[x2, y1 - 1] - s[x1 - 1, y2] + s[x1 - 1, y1 - 1]

int x1, y1, x2, y2;
int main(){
    cin >> x1 >> y1 >> x2 >> y2;
    cout << '('<<x1 <<','<< y1<< ')' <<'('<<x2 <<','<< y2<<')' << endl;
    cout << sum[x2][y2] - sum[x2][y1-1] - sum[x1-1][y2] + sum[x1-1][y1-1]<<endl;
}

总结

前缀和是一个非常有用的知识点,常用于解决一些涉及数组或列表的问题。前缀和的概念很简单:对于一个数组,如果我们要知道从索引0到当前位置的元素之和,我们只需要将当前位置的元素加上前面所有元素的和。这个和就是前缀和。
前缀和的优点是可以显著降低时间复杂度。例如,如果我们想找到一个数组中的累计和,使用前缀和可以在O(n)的时间复杂度内完成,而不用遍历整个数组。

在编程中,我们可以通过以下方式计算前缀和:

使用循环:遍历数组,每次计算从0到当前位置的元素之和。
使用数据结构:如使用哈希表或前缀和数组。对于这种数据结构,我们需要遍历一次数组来
计算前缀和,但之后查询前缀和的时间复杂度就是O(1)。

标签:x1,前缀,sum,x2,y1,y2
From: https://www.cnblogs.com/ywx1207/p/17849825.html

相关文章

  • 哈夫曼编码及前缀码的实现
    哈夫曼编码我们的任务是选一篇英语文章统计每个字符的概率,并实现哈夫曼前缀编码所选文章内容:lifeistooshorttospendtimewithpeoplewhosuckthehappinessoutofyouifsomeonewantsyouintheirlifetheyllmakeroomforyouYoushouldnthavetofightfor......
  • DHCPv6 PD(Prefix Delegation)前缀代理
    概念DHCPv6前缀代理DHCPv6PD(PrefixDelegation)是一种前缀分配机制,通过DHCPv6前缀代理机制,下游网络设备不需要再手工指定用户侧链路的IPv6地址前缀,它只需要向上游网络设备提出前缀分配申请,上游网络设备便可以分配合适的地址前缀给下游设备,下游设备把获得的前缀再通过路由通告(RA)......
  • 数据加WJ前缀
    你好,我将给你一个地址,请你遍历地址和地址下所有子文件夹,里面有很多图片名称,如"Goldwatch_Bluehexagonaldial_Goldnumbersandpointers_Goldstrap"每个下划线作为分割的符号,下划线间的字符作为一个单元。如:“Goldwatch_Bluehexagonaldial_Goldnumbersandpointers......
  • CF1304E 1-Trees and Queries(lca+树上前缀和+奇偶性)
    题目二话不说,直接按题意模拟暴搜,当然\(O(nq)\)的复杂度显然是寄了的。不过,在模拟的过程中,我在链式前向星的删边中居然一开始错了,还是要mark一下以后注意。voiddel(intx,intpre){ e[top].to=e[top].next=0; h[x]=pre;//h[x]=0;<---tip}intmain(){ ......
  • 10-前缀树
    10.前缀树(trie)8.1前缀树概念1.前缀树概念1)单个字符串中,字符从前到后的加到一棵多叉树上2)字符放在路上,节点上有专属的数据项数据项pass:有多少路径经过了这个点数据项end:有多少路径是以这个点结尾3)所有样本都这样添加,如果没有路就新建,如有路就复用4)沿途节点的pass值增......
  • 前缀和+差分数组
    一、一维数组度前缀和--固定数组查询区间和1.1定义对于给定一个数组arr(下标从0开始),它的前缀和S[i]表示从arr[0]到arr[i]元素总和。1.2构造前缀和S[i]=S[i-1]+arr[i-1]1.3应用-求某个区间的和计算区间[i,j]的元素和=>arr[i]+arr[i+1]+arr[i+2]+……+a......
  • 前缀和
    AcWing笔记——前缀和前言数组的前缀和,代表着一个数组前N个数的和。主要用于优化这样一种场景:当题目要求进行求出一个数组从下标\(i\)到下标\(j\)之间的元素的和,且会多次进行这种操作时,我们可以使用前缀和的方法来优化求和的过程。时间复杂度对比:若使用for循环遍历整......
  • 【进阶算法】一维数组的前缀和
    前缀和是指数组某个索引之前的所有元素的和,是一种重要的预处理手段,使用前缀和可以快速求出数组某一个区间的和。 示例:数组arr=[8,1,3,-2,5,0,-3,6],输入m个询问,每个询问输入一对l,r。对于每个询问,要求输出原数组中从第l个数到第r个数的和。比如,第1次询问,输入[0,2],需要输出1......
  • 前缀和习题汇总
    一、洛谷p1147连续自然数和题目描述对一个给定的正整数\(M\),求出所有的连续的正整数段(每一段至少有两个数),这些连续的自然数段中的全部数之和为\(M\)。例子:\(1998+1999+2000+2001+2002=10000\),所以从\(1998\)到\(2002\)的一个自然数段为\(M=10000\)的一个解。输入格......
  • 前缀和差分
    前缀和什么是前缀和:简单来说,有一个\(x\)数组和\(y\)数组,\(y\)是\(x\)的前缀和数组。\(y_1=x_1\)\(y_2=x_1+x_2\)\(y_3=x_1+x_2+x_3\)\(y_n=x_1+x_2+x_3+……+x_n\)求区间和求前缀和的公式r[i]=r[i-1]+s[i]\(r\)为前缀和数组,要求\(x\)到\(y\)的区间和的话,那么......