对于数组a[n]
用s数组来记录, s[i]=a1+a2+a3.....+ai;
注意:前缀和下标要从一开始
1.那么如何求s[i]
2.s[i]用来干什么
1.for(int i=1;i<=n;i++)
{
s[i]=a[i]+s[i-1];
}
2.作用:快速求a[l] 到a[r]的和,即s[r]-s[l-1]
将时间复杂度由o(n) 降低到 o(1)
代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int n ,m,r,l;
int a[N],s[N];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++ ) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
while(m--)
{
scanf("%d%d",&l,&r);
printf("%d\n",s[r]-s[l-1]);
}
}
二维前缀和

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int n,m,k;
int a[N][N],s[N][N];
int main()
{ scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d" ,&a[i][j]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
}
}
while(k--)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
printf("%d\n",s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]);
}
return 0;
}
下面是差分,差分与前缀和互为逆运算,
对于已知数组a提供一个b数组
使得b数组的前缀和是a,那么就说b是a的差分
差分的作用 用o(n)时间,由b数组得到a数组
对于给定区间[l,r]让a数组+c,时间复杂度o(n) ,用差分来做就只用o(1)
方法:让b[l]+c,b[r+1]-c
同时,对于a数组,可以看出数组内全是零,读入数组可以看出是差分数组b进行了n次插入,每次插入,对于a1则是b[1]+c,b[2]-c
这样就不用考虑差分数组是怎么来的了
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int a[N],b[N];
int n,m;
void insert(int l,int r,int c)
{
b[l]+=c;
b[r+1]-=c;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) insert(i,i,a[i]);
while(m--)
{
int l,r,c;
scanf("%d%d%d",&l,&r,&c);
insert(l,r,c);
}
for(int i=1;i<=n;i++) b[i]+=b[i-1];
for(int i=1;i<=n;i++) printf("%d",b[i]);
}
下面是二维差分

下面是代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int n,m,p;
int a[N][N],b[N][N];
void insert(int x1,int y1,int x2,int y2,int c)
{
b[x1][y1]+=c;
b[x1][y2+1]-=c;
b[x2+1][y1]-=c;
b[x2+1][y2+1]+=c;
}
int main()
{
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
insert(i,j,i,j,a[i][j]);
}
}
while(p--)
{ int z,x,c,v,y;
scanf("%d%d%d%d%d",&z,&x,&c,&v,&y);
insert(z,x,c,v,y);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf(" %d",b[i][j]);
}
printf("\n");
}
return 0;
}

1937

被折叠的 条评论
为什么被折叠?



