前缀与差分

前缀

前缀的是指使用sum[NMAX] 来表示 arr[NMAX] 的前缀和
即:
sum[n] = arr[0] + arr[1] + ... arr[n-1]+arr[n]

差分

差分是指使用d[NMAX] 来表示arr[NMAX] 的差项
即:
d[0] = arr[0]
d[1] = arr[1]-arr[0]
d[2] = arr[2]-arr[1]
.....
d[n] = arr[n]-arr[n-1]

两者关系

前缀和差分,两人个就是互补。
前缀和数组的差分,为arr原数组
差分数组的前缀和,为arr原数组


区间改变

差分在求解范围修改数组数据时,有奇效。(当需要求出arr原数组时,只需要计算前缀和即可)
比如,需要在A~B的所有数字都减1,则:
d[A+1] --; d[B]++;即可。
因为d[A+1]=arr[A+1]-arr[A] = -1 ;
d[B]=arr[B]-arr[B-1] = 1;
而其它不变
这样,就将O(n)问题转化成O(1)了


附:poj3263ac代码

#define NMAX 10004

int d[NMAX];

int main(){
	int N,I,H,R;
	scanf("%d%d%d%d",&N,&I,&H,&R);
	set<int> rangeSet;
	int A,B;
	for( int i=0;i<R;++i ){
		scanf("%d%d",&A,&B);
		if ( A > B ) swap(A,B);
		int v = (A << 15) | B;//因为最大只到10000
		if ( rangeSet.find(v) == rangeSet.end() ){
			rangeSet.insert(v);
			d[A+1] --;
			d[B] ++;
		}
	}
	int sum = 0;
	for( int i=1;i<=N;++i ){
		sum += d[i];
		printf("%d\n",H+sum);
	}
	return 0;
}
posted @ 2022-02-18 18:36  传说中的水牛  阅读(51)  评论(0编辑  收藏  举报