前缀和进阶
各种奇怪题目的优化有奇效!
前缀和算法可以在常数时间复杂度内计算给定区间i~j的和,而从头扫一遍的复杂度为O(n);而二维前缀和则可以在常数时间内计算(x1,y1)到(x2,y2)矩阵内的和,而从头扫一遍为O(n^2)!!
一维前缀和
给定n个数,m组询问,求i~j区间的和
上次讲用线段树做,但前缀和更方便一些。
设s[i]表示第一个数加到第i个数的和,则sum(i,j)=s[j]-s[i-1]
而预处理又可以随读入一起完成,效率就很高了。
1 | scanf("%d",&n); |
二维前缀和
由一维可以推广到二维:计算从(x1,y1)到(x2,y2)的矩阵的和。
这个优化就更加明显了,直接从O(n^2)降到了O(1)。
设s[i][j]表示从(0,0)到(i,j)的矩阵的和
由容斥原理,sum(x1,y1,x2,y2)=s[x2][y2]-s[x1][y2-1]-s[x2-1][y1]+s[x1-1][y1-1]
1 | scanf("%d",&n); |
就这样,又方便又快