差分
差分:
当频繁的对数组内的元素进行区域性性的加减运算的时候使用差分
差分数组的第一个值等于源数组的第一个值
差分数组的第k个值等于原数组第k个值减去第k-1个值
当要让原数组的 [L,R]区域内每个元素都 加/减 c的时候
只需要差分数组的[L](+/ -)c,差分数组的[R+1](-/+)c
最后原数组的结果等于差分数组的前缀和数组
题目:

输入样例:
6 3 1 2 2 1 2 1 1 3 1 3 5 1 1 6 1
期望输出:
3 4 5 3 4 2
代码实现:
#include<bits/stdc++.h>
using namespace std;
const int N =1e6+10;
int n,m;
int a[N],b[N];
int main()
{
cin>>n>>m;
//输入a数组元素并且预处理差分数组b
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]= a[i] - a[i-1];
}
while(m--)
{
int l ,r,k;
cin>>l>>r>>k;
b[l]+=k;
b[r+1]-=k;
}
int t = 0;
//对b数组求前缀和即可得到最终数列
for(int i=1;i<=n;i++)
{
t=t+b[i];
printf("%d ",t);
}
}
------------------------------------------------------------------------------------------------------------------------------------
二维差分
二维差分数组b[i,j]要使原数组a[i,j]是右上角所有b[i,j]元素的前缀和
要使的某个区间同时加上一个数c,只需要把 b[x1,y1] +c , b[x1,y2 +1] +c , b[x2 +1,y1] -c , b[x2 +1,y2 +1] +c

题目:

输入样例:
3 4 3 1 2 2 1 3 2 2 1 1 1 1 1 1 1 2 2 1 1 3 2 3 2 3 1 3 4 1
期望输出:
2 3 4 1 4 3 4 1 2 2 2 2
代码实现:
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n,m,q;
int a[N][N],b[N][N];
int main()
{
cin>>n>>m>>q;
//输入a数组并且预处理得到差分数组b
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
b[i][j]=a[i][j] -a[i-1][j] -a[i][j-1] +a[i-1][j-1];
}
}
int x1,y1,x2,y2,c;
//对差分数组进行操作
while(q--)
{
cin>>x1>>y1>>x2>>y2>>c;
b[x1][y1]+=c;
b[x1][y2+1]-=c;
b[x2+1][y1]-=c;
b[x2+1][y2+1]+=c;
}
//此时b仍然是差分数组,是处理完成后的差分数组,对b求前缀和,得到结果数组
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+b[i][j];
printf("%d ",a[i][j]);
}
puts("");
}
}

浙公网安备 33010602011771号