最为重要的是前缀思想以及对一个问题的预处理方式
// 前缀和问题用于连续求和中某一段中的具体值 也用于公共前缀的某些操作
// 思想为 把前面的数用一种状态进行记录下
// 也包含了预处理的思想
// 作为最基础算法之一出现次数十分之多 此思想十分重要
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N];
int n,m;
int main ()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
a[i]+=a[i-1];
}
while (m -- )
{
int l,r; cin>>l>>r;
cout<<a[r]-a[l-1]<<endl;
}
return 0;
}
//作为前缀和的最基础运用
// 由二维的数组构成考虑本身进行加数构成前缀和数组
// 考虑到底如何删除以及如何遍历
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m,q;
int s[N][N];
int main ()
{
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>s[i][j];
s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
}
while(q--)
{
int x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2;
cout<<s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]<<endl;
}
return 0;
}
// 作为前缀和的逆运算 差分的作用十分之大
//还用于使用map或者离散化来进行求某些需要修改的数
// 把差分进行前缀和就是本身数组
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N];
int n,m;
int main ()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int c;cin>>c;
a[i]+=c,a[i+1]-=c;
}
while(m--)
{
int l,r,c; cin>>l>>r>>c;
a[l]+=c,a[r+1]-=c;
}
for(int i=1;i<=n;i++) a[i]+=a[i-1];
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
return 0;
}
//子矩阵的逆运算所以是类似的主要是要对谁处理
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int s[N][N],a[N][N];
int n,m,q;
void insert(int x1,int y1,int x2,int y2,int c)
{
s[x1][y1]+=c;
s[x1][y2+1]-=c;
s[x2+1][y1]-=c;
s[x2+1][y2+1]+=c;
}
int main ()
{
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>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(q--)
{
int l1,r1,l2,r2,c; cin>>l1>>r1>>l2>>r2>>c;
insert(l1,r1,l2,r2,c);
}
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];
cout<<s[i][j]<<" ";
}
cout<<endl;
}
return 0;
}