【基础算法】

本文深入探讨了前缀和与差分这两种算法,它们分别用于快速求解数组区间和以及高效修改数组元素。前缀和允许在常数时间内获取任意区间之和,而差分数组则支持在O(1)时间内对数组区间进行加法操作。通过实例解析了二维差分在矩阵操作中的应用,展示了如何进行二维矩阵的快速更新。这些技术在解决数组和矩阵问题时具有重要的实践价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础算法

前缀和
作用:

任意求一段范围内的值,o(1)的时间复杂度。

思路:

1、计算前缀和矩阵(容斥原理)
前缀和数组
前缀和:S(x,y)= S(x-1,y)+S(x,y-1)+a(x,y)-S(x-1,y-1) 注意:数组下标为1
例如:21=17+10+2-8

2、在前缀和矩阵种求出子矩阵和
子矩阵和
子矩阵和为A=S(x2,y2)-S(x2,y1-1)-S(x1-1,y2)+S(x1-1,y1-1)
例如6+2+1+2=26-6-10+1

练习题目

链接: 前缀和

差分
作用:

给原数组中间某一段连续区间加一个固定值,o(1)
原数组 :a1,a2,a3…
差分数组:
b1=a1
b2=a2-a1
b3=a3-a2
bn=an-a(n-1)
最后操作的原数组为:
a1=b1
a2=b1+b2
a3=b1+b2+b3
ai=b1+b2+b3+…+bi
一维差分

伪代码
//给temp数组[L,R]区间加上C
int temp[N],b[N];
void insert(int l,int r,int c){
    b[l]+=c;
    b[r+1]-=c;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&temp[i]);
        //初始化差分数组
        insert(i,i,temp[i]);
    }
    while(m--){
        int l,r,c;
        scanf("%d%d%d",&l,&r,&c);
        insert(l,r,c);
    }
    //原数组
    for(int i=1;i<=n;i++){
        b[i]+=b[i-1];
        cout<<b[i]<<" ";
    }
练习题目

链接: 差分

二维差分

作用:给其中子矩阵加上一个值
二维矩阵差分
求差分b(i,j)
b(x1,y1)+=C 相当于右下角正方形全部加C
b(x2+1,y1)-=C 相当于橘色部分的全部减去C
b(x1,y2+1)-=C 相当于白色部分全部减去C
b(x2+1,y2+1)+C,这个部分减去了2个C,实际只需要减去一个
求给元素在加C后:
对差分b,进行二维前缀求和

伪代码
int insert(int x1,int y1,int x2,int y2,int c){
	b[x1][y1]+=c;
	b[x2+1][y1]-=c;
	b[x1][y2+1]-=c;
	b[x2+1][y2+1]+=c;
	return 0;
}
int main(){
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=m;j++)
	     {
	     	scanf("%d",&a[i][j]);
	     	insert(i,j,i,j,a[i][j]); 
	     }
	while(q--){
	  int x1,y1,x2,y2,c;
	  scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&c);
	  insert(x1,y1,x2,y2,c);
	}
	//求前缀和
	for(int i=1;i<=n;i++)
	  {
	  for(int j=1;j<=m;j++){
	  	b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
		 cout<<b[i][j]<<" "; 
	  }
练习题目

链接: 二维差分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值