标签:scan 变化 矩阵 前缀和 二维 void 变形 turn pac
定义
s[n] = \(\sum_{i=1}^na[i]\)
递推关系
s[i] = a[i] + s[i - 1]
区间求和
\(\sum_{i=l}^ra[i] = s[r] - s[l - 1]\)
定义
存在两个数组a(a1, a2, a3,..., an)和b(b1, b2, ... ,bn)
如果ai = b1 + b2 + ... + bi
那么b称为a的差分(比如: b1 = a1, b2 = a2 - a1)
作用
构造
差分的构造可以选择: b[i] = a[i] - a[i - 1]
变形
差分可以维护a的变化值,即b[i] = Δai = $ \sum_{i=1}^nb[i] $
#include <bits/stdc++.h>
using namespace std;
int const N = 1e5 + 10;
int s[N], a[N];
int main()
{
int n, k;
cin >> n >> k;
// 计算前缀和
for (int i = 1; i <= n ; ++i)
{
scanf("%d", &a[i]);
s[i] = s[i - 1] + a[i];
}
// 使用前缀和
for (int i = 0; i < k ; ++i)
{
int l, r;
scanf("%d %d", &l, &r);
printf("%d\n", s[r] - s[l -1]);
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int const N = 1e3 + 10;
int s[N][N], a[N][N];
int main()
{
int n, m, k;
cin >> n >> m >> k;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
{
scanf("%d", &a[i][j]);
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j]; // 前缀和在二维的情况
}
for (int i = 0; i < k; ++i)
{
int l1, r1, l2, r2;
scanf("%d %d %d %d", &l1 ,&r1, &l2, &r2);
printf("%d\n", s[l2][r2] - s[l2][r1 - 1] - s[l1 - 1][r2] + s[l1 - 1][r1 - 1]); // 打印结果
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int const N = 1e5 + 10;
int b[N], n, m, a[N];
// 区间修改
void insert(int l, int r, int c) {
b[l] += c, b[r + 1] -= c;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); // 读入原数组
for (int i = 1, l, r, c; i <= m; ++i) { // 不断读入区间增加
scanf("%d %d %d", &l, &r, &c);
insert(l, r, c);
}
for (int i = 1; i <= n; ++i) {
b[i] += b[i - 1]; // 计算a[i]的变化值
printf("%d ", a[i] + b[i]);
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int const N = 1e3 + 10;
int a[N][N], b[N][N];
int n, m, q;
// 区间增加(二维情况)--和前缀和情况不一样
void insert(int l1, int r1, int l2, int r2, int c)
{
b[l1][r1] += c;
b[l2 + 1][r2 + 1] += c;
b[l2 + 1][r1] -= c;
b[l1][r2 + 1] -= c;
}
int main() {
cin >> n >> m >> q;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) scanf("%d", &a[i][j]); // 读入原来矩阵
}
for (int i = 1, l1, r1, l2, r2, c; i <= q; ++i) {
scanf("%d%d%d%d%d", &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) {
b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1]; // 前缀求和,计算变化量
printf("%d ", a[i][j] + b[i][j]); // 计算变化后的a[i][j]
}
printf("\n");
}
return 0;
}
标签:scan 变化 矩阵 前缀和 二维 void 变形 turn pac
原文地址:https://www.cnblogs.com/spciay/p/13064104.html