1.前缀和与差分
hainoir1.prefix 前缀和数组
p[i] = p[i-1] + a[i];
优点:便于数组查找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <bits/stdc++.h> using namespace std; using ll =long long; const int N = 1e5+9; ll a[N],p[N];
int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T;cin >> T; while(T--){ ll n,q;cin >> n >> q; for(int i = 1;i <= n;i++){ cin >> a[i]; } for(int i = 1;i <= n;i++){ p[i] = p[i-1] + a[i]; } while(q--){ ll l,r;cin >> l >> r; cout << p[r] - p[l-1] << '\n'; } } }
|
2.diff 差分数组
d[i] = a[i] - a[i-1];
优点:便于数组修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <bits/stdc++.h> using namespace std; using ll =long long ; const int N = 1e5+9; ll a[N],c[N],d[N];
int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); ll n,p,q;cin >> n >> p >> q; for(int i = 1;i <= n;i++)cin >> a[i]; for(int i = 1;i <= n;i++)d[i] = a[i] - a[i-1]; while(p--){ ll l,r,x;cin >> l >> r >> x; d[l] += x;d[r+1] -= x; } for(int i = 1;i <= n;i++)a[i] = a[i - 1] + d[i]; for(int i = 1;i <= n;i++)c[i] = c[i - 1] + a[i]; while(q--){ ll l,r;cin >> l >> r; cout << c[r] - c[l-1] << '\n'; } }
|
3.二位前缀和
p[i][j] = p[i-1][j] + p[i][j-1] - p[i-1][j-1] + a[i][j];
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include <bits/stdc++.h> using namespace std; const int N = 1e3+9; using ll = long long; ll a[N][N],p[N][N];
int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); 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];
for(int i = 1;i <= n;++i) for(int j = 1;j <= m;++j) p[i][j] = p[i-1][j] + p[i][j-1] - p[i-1][j-1] + a[i][j]; while(q--){ int res = 0; int x1,y1,x2,y2;cin >> x1 >> y1 >> x2 >> y2; res = p[x2][y2] - p[x1-1][y2] - p[x2][y1-1] + p[x1-1][y1-1]; cout << res << '\n'; } }
|
4.二维差分
1.差分求法
d[i][j] = a[i][j] - a[i-1][j] - a[i][j-1] + a[i-1][j-1]
以上这个求法,是将原式作为所求差分的前缀和。
2.标准求法
d[i][j] += a[i][j];
d[i + 1][j] -= a[i][j];
d[i][j + 1] -= a[i][j];
d[i + 1][j + 1] += a[i][j];
两种求法一样,可以互相推导
eg:d[i + 1][j] -= a[i][j]; =
d[i][j] -= a[i-1][j]`
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
#include<bits/stdc++.h> using namespace std; using ll = long long;
const int N = 1e3+10; ll a[N][N], d[N][N];
int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); 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]; d[i][j] += a[i][j]; d[i + 1][j] -= a[i][j]; d[i][j + 1] -= a[i][j]; d[i + 1][j + 1] += a[i][j]; } } while (q--) { int x1, x2, y1, y2, c; cin >> x1 >> y1 >> x2 >> y2 >> c; d[x1][y1] += c; d[x1][y2 + 1] -= c; d[x2 + 1][y1] -= c; d[x2 + 1][y2 + 1] += c; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + d[i][j]; cout << a[i][j] << ' '; } cout << '\n'; } return 0; }
|