一维前缀和
一、定义
arr[n] 给定的一维数组
sum[n] 表示arr前缀和的一维数组
其中 sum[i]=arr[0]+arr[1]+...+arr[n-1]+arr[n]
即,sum[i]为arr前i个数之和
# arr[n]初始数组
# sum[n]前缀和数组
sum[0] = arr[0] #对sum[0]赋初值
for i in range(1,n,1): #利用递推对sum赋值
sum[i]=sum[i-1]+arr[i]
二、应用
求区间之和
[例] 求arr区间[l,r](左包含右包含)之和
普通方法:ans=arr[l]+arr[l+1]+...+arr[r]
前缀和:ans=sum[r]-sum[l-1] (还需考虑l==0的情景)
if l==0:
ans=sum[r]
else:
ans=sum[r]-sum[l-1]
二维前缀和
一、定义
arr[n][m] 给定的二维数组
sum[n][m] 表示arr前缀和的二维数组
sum[i][j]=arr[0][0]与a[i][j]所构成矩形的所有值之和(即图中蓝色矩形部分)
①对sum[0][0]赋值
②对第一行第一列赋值,本质与一维前缀和相同
③对sum[i][j]赋值 sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+arr[i][j](如图所示)
(图片来源:林晓鹿@)
#arr[n][m]初始数组
#sum[n][m]前缀和数组
sum[0][0]=arr[0][0] #对sum[0][0]赋值
for j in range(1,m,1):
sum[0][j]=sum[0][j-1]+arr[0][j] #对第一行赋值
for i in range(1,n,1):
sum[i][0]=sum[i-1][0]+arr[i][0] #对第一列赋值
for i in range(1,n,1):
for j in range(1,m,1):
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+arr[i][j]
二、应用
求区块之和
[例] 求arr区块之和左上角角标(x1,y1)右下角角标(x2,y2)
普通方法:暴力求解
前缀和:
①x1==0 and y1==0 ans=sum[x2][y2]
②x1==0 and y1>=1 ans=sum[x2][y2]-sum[x2][y1-1]
③y1==0 and x1>=1 ans=sum[x2][y2]-sum[x1-1][y2]
④x1>=1 and y1>=1 ans=sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1]
if x1==0 and y1==0:
ans=sum[x2][y2]
elif x1==0 and y1>=1:
ans=sum[x2][y2]-sum[x2][y1-1]
elif y1==0 and x1>=1:
ans=sum[x2][y2]-sum[x1-1][y2]
else:
ans=sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1]