一、前缀和解决问题
给出一个长度为N的数组A[],并进行q组询问,每次询问给出一个区间[l,r],需要求区间[l,r]的数组元素和(即A[l]+…+A[r]的值),若用for循环每次询问,时间复杂度为:O(N*q),性能较低。我们可以:
令前缀和数组Sum[i]=A[1]+A[2]+…+A[i]
·不难发现
Sum[l-1]=A[1]+…+A[l-1]
Sum[r]=A[1]+……+A[l-1]+A[l]+…+A[r]
A[l]+…A[r]=Sum[r]-Sum[l-1]
这样每次询问就被优化到了O(1),总复杂度为O(q)。
二、例题
部分算法如下:
上述代码时间复杂度为O(N^2).
考虑优化
利用公式(a-b)%k=(a%k-b%k)%k
把(sum[j]-sum[i-1])%k==0转化成
sum[j]%k==sum[i-1]%k
优化后:
三、二维前缀和
·(1)利用前缀和求a[i][j]
S蓝=S绿- S红- S黄+S粉
·a[i][j]=s[i][j]-s[i-1][j]-s[i][j-1]+s[i-1][j-1]
(2)已知a[i][j],求s前缀和数组
S绿=S黄+S红-S粉+a[i][j],S黄S红S粉由递推得出。
四、二维前缀和例题
代码如下: