一. 我的思想
这两个算法十分重要,需要牢牢记住,然后灵活使用!
二.一维前缀和
核心代代码:
1.初始化的时候:
p[i] = p[i - 1] + a[i];
2.计算的时候,其实和等差数列差不多啦:
ans=p[r] - p[l - 1];
上题目:
上代码:
#include<bits/stdc++.h>
using namespace std;
int a[100006],p[100006]={0};
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <=n;i++)
{
cin >>a[i];
p[i] = p[i - 1] + a[i];//核心部分
}
while(m--)
{
int l, r;
cin >> l >> r;
if(l>r)
{
swap(l,r);
}
int ans=p[r] - p[l - 1];//核心部分
cout<<ans<<endl;
}
}
这个还是非常简单的。
三.一维差分
注意要先全修改完,再相加
核心代码
void insert(int l,int r,int c)
{
b[l] += c;
b[r + 1] -= c;
}
就是与前一项的差值,l到r的部分都加上一个常数,然后加起来就可以得到答案啦。
上代码
#include<bits/stdc++.h>
using namespace std;
int a[100005], b[100005];
void insert(int l,int r,int c)//上面讲的核心代码
{
b[l] += c;
b[r + 1] -= c;
}
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n;i++)
{
cin >> a[i];
insert(i, i, a[i]);
}
while(m--)
{
int l, r, c;
cin >> l >> r >> c;
insert(l, r, c);
}
for (int i = 1; i <= n;i++)
{
b[i] += b[i - 1];//当前的数组与前一项的差值加上前一数组的值就是答案
cout << b[i] << ' ';
}
}
四.二维前缀和
我一般画图理解。
核心代码部分:
1.初始化:
sum[i][j] = a[i][j] + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
2.计算结果:
sum[x3][y3] - sum[x3][y2 - 1] - sum[x2 - 1][y3] + sum[x2 - 1][y2 - 1]
上题目:
上代码:
#include<bits/stdc++.h>
using namespace std;
int a[10005][10005];
int sum[10005][10005];
int main()
{
int n, m, q;
cin>>n>>m>>q;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m;j++)
{
cin >> a[i][j];
sum[i][j] = a[i][j] + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
}
}
while(q--)
{
int x2, x3, y2, y3;
cin >> x2 >> y2 >> x3 >> y3;
cout << sum[x3][y3] - sum[x3][y2 - 1] - sum[x2 - 1][y3] + sum[x2 - 1][y2 - 1]<<endl;
}
}
二维差分
也是画图理解,就容易记了。
核心代码
初始化:
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;
}
计算每一项的值:
b[i][j] = b[i][j] + b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
上题目:
代码!:
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
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()
{
int n,m,q;
cin>>n>>m>>q;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m;j++)
{
cin >> a[i][j];
insert(i, j, i, j, a[i][j]);
}
}
while(q--)
{
int x1, y1, x2, y2, c;
cin >> x1 >> y1 >> x2 >> y2 >> c;
insert(x1, y1, x2, y2, c);
}
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m;j++)
{
b[i][j] = b[i][j] + b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
cout << b[i][j] << ' ';
}
cout << endl;
}
}
#六.总结
这个要好理解我认为要画图动脑理解,这两个算法很容易和别的一起出我这有个以前写的他和二分一起出的题:换教室:二分+差分
就是这个。加油多刷题!!!