前缀和、差分

一维前缀和

前缀和是一项很重要的预处理,可以大大降低算法的复杂度。我们可以理解为数组的前i项和.
给出数组a[1]、a[2]、a[3]…a[n].
设前缀和数组s[i]=a[1]+a[2]+…+a[i]
如果我们要算出a[3]+a[4]+…+a[15]的值,可以利用前缀和数组s[15]-s[3-1].
s[l,r]=s[r]-r[l-1].

void init(){
	for(int i=1;i<=n;i++)
	sum[i]=sum[i-1]+a[i];
}
int get(int l,int r){
	return sum[r]-sum[l-1];
}

二维前缀和

对于二维数组,前缀和数组sum[i][j]表示a[1…i][1…j]之和.也就是以所有点为右下角,(1,1)为左上角中的矩阵的和.
利用容斥原理
在这里插入图片描述

void init(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+a[i][j];
		}
	}
}
int get(int x1,int y1,int x2,int y2){
	return sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1];
}

一维差分

差分是一种和前缀和相对的策略
这种策略是b[i]=a[i]-a[i-1],b[1]=a[1].即相邻两数之差.b[i]的前缀和就是a[i]
a[1,2…,n]
b[i]=a[i]-a[i-1],b[1]=a[1].
差分数组可用于区间的修改和查询

void init(int l,int r,int num){
	b[l]+=num,b[r+1]-=num;
}
int get(){
	for(int i=1;i<=n;i++){
		a[i]=a[i-1]+b[i];
	}
}

二维差分

void init(int x1,int y1,int x2,int y2,int num){
	b[x1][y1]+=num;
	b[x1][y2+1]-=num;
	b[x2+1][y1]-=num;
	b[x2+1][y2+1]+=num;
}
void get(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			b[i][j]+=b[i][j-1]+b[i-1][j]-[i-1][j-1];
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值