1.前缀和
前缀和提供一个时间复杂的为O(1)的区间查询。通过前缀和右端点与左端点-1之差可以得到其区间和。
本题链接:
【模板】前缀和 | 星码StarryCoding | 算法竞赛新手村 | ACM、OI、蓝桥杯、天梯赛、CCF、ACM-ICPC、大学生信息学竞赛
今日题解如下:
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
| #include<bits/stdc++.h> using namespace std; using ll = long long;
const int N = 1e5 +9; ll a[N], pre[N];
int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t; cin>>t; while(t--) { int n,q; cin >> n >> q; for(int i = 1; i <= n; ++i)cin>>a[i]; for(int i = 1; i <= n; ++i)pre[i] = pre[i-1] + a[i];
while(q--) { int l, r; cin>>l>>r; cout << pre[r] -pre[l - 1] << '\n'; } }
return 0; }
|
粗心的把ll = long long 写成ll = int;导致结果错误。
2.差分
差分便于区间修改,可以通过前缀和得到前缀和数组,然后利用前缀和得到修改后的区间和。
原题链接:
【模板】差分 | 星码StarryCoding | 算法竞赛新手村 | ACM、OI、蓝桥杯、天梯赛、CCF、ACM-ICPC、大学生信息学竞赛
今日题解:
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
| #include<bits/stdc++.h> using namespace std; using ll = long long; const int N = 1e5 + 9; ll a[N],diff[N],pre[N];
void solve() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n,p,q; cin>>n>>p>>q; for(int i=1;i<=n;++i) { cin>>a[i]; } for(int i=1;i<=n;++i) { diff[i] = a[i] - a[i-1]; } while(p--) { int l,r,x; cin>>l>>r>>x; diff[l]+=x; diff[r+1]-=x; } for(int i=1;i<=n;++i) { a[i]=a[i-1]+diff[i]; } for(int i=1;i<=n;++i) { pre[i]=pre[i-1]+a[i]; } while(q--) { int l,r; cin>>l>>r; cout<<pre[r] - pre[l-1]<<'\n'; } }
int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t=1;
while(t--) { solve(); } return 0; }
|
3.二维前缀和
原题链接:
【模板】二维前缀和 | 星码StarryCoding | 算法竞赛新手村 | ACM、OI、蓝桥杯、天梯赛、CCF、ACM-ICPC、大学生信息学竞赛
今日题解:
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
| #include<bits/stdc++.h> using namespace std; using ll = long long;
const int N = 1e3 + 9; ll a[N][N], pre[N][N];
void solve() { 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) { pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j]; } } while(q--) { int x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2; cout<<pre[x2][y2]-pre[x2][y1-1]-pre[x1-1][y2]+pre[x1-1][y1-1]<<'\n'; } }
int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t=1;
while(t--) { solve(); } return 0; }
|
图1:

图2:
