一维前缀和
1.推导
假设有5个数,原数组为a[n],前缀和数组为b[n]
a1,a2,a3,a4,a5;
i=1 b[1]=a[1];
i=2 b[2]=a[1]+a[2];
=b[1]+a[2];
i=3 b[3]=a[1]+a[2]+a[3];
=b[2]+a[3];
i=4 b[4]=a[1]+a[2]+a[3]+a[4];
=b[3]+a[4];
i=5 b[5]=a[1]+a[2]+a[3]+a[4]+a[5];
=b[4]+a[5];
由此可以推出来
当i=1 b[1]=a[1];
其他 b[i]=b[i-1]+a[i](2<=i<=n);
2.模板
int n;
int a[N]={0},b[N]={0};
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(i=1;i<=n;i++)
{
b[i]=b[i-1]+a[i];
}
二维前缀和
1.推导+模板
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+a[i][j];
}
}
2.求某个子矩阵的和
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
int ans=f[x2][y2]-f[x2][y1-1]-f[x1-1][y2]+f[x1-1][y1-1];//下标从1开始
cout<<ans<<endl;
3.求某个边长为r的正方形的和
for(i=1;i<=1001;i++)
{
for(j=1;j<=1001;j++)
{
int t=f[i][j]-f[i-r][j]-f[i][j-r]+f[i-r][j-r];
ans=max(ans,t);
}
}