前缀与差分
前缀
前缀的是指使用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;
}