ACwing(基礎)--- 字首和、差分
阿新 • • 發佈:2020-08-23
一維字首和
顧名思義:字首和就是陣列前n項和
注意:陣列下標從1開始防止越界
1、預處理字首和陣列
2、用公式求區間和
//求字首和
s[i] = s[i-1]+a[i];
//求陣列下標在l,r之間的元素之和
s[r]-s[l-1]
二維字首和
用二維矩陣來計算
// 求s[i,j] 表示矩陣大小為行i,列j的元素之和
s[i][j] = s[i-1][j]+s[i][j-1] - s[i-1][j-1] + a[i][j];
// 求s[x1,y1]到s[x2,y2]之間的元素之和
s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];
#include<iostream> using namespace std; const int N = 1010; int n,m,q; int a[N][N],s[N][N]; int main(){ cin >> n >> m >> q; for(int i = 1; i <= n; i ++ ){ for(int j = 1; j <= m; j ++ ){ cin>>a[i][j]; s[i][j] = s[i-1][j]+s[i][j-1] - s[i-1][j-1] + a[i][j]; } } while(q -- ){ int x1,x2,y1,y2; cin>>x1>>y1>>x2>>y2; cout<<s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]<<endl; } return 0; }
一維差分
給定a[1],a[2],...a[n]構造差分陣列b[N],使得a[i] = b[1]+b[2]+...+b[i]
b[i]=a[i]-a[i-1];
核心操作:將a[L~R]全部加上C,等價於:b[L]+=C,b[R+1] -= C;
1、a[1~L-1]無影響
2、a[L~R]加上了C
3、a[R+1~N]無影響
實現差分
有的操作利用了字首和,差分是字首和的逆運算
// b[N] 初始全為0 void insert(int l,int r,int c){ b[l]+=c; b[r+1]-=c; } //利用字首和來還原陣列資料 for(int i = 1; i <= n; i ++ ) a[i] = a[i-1] + b[i]; //整體操作:計算差分陣列b[N],將序列中[l, r]之間的每個數加上c,還原原陣列 #include<iostream> using namespace std; const int N = 1e5+10; int n,m; int a[N],b[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 ++ ) cin>>a[i]; for(int i = 1; i <= n; 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 ++ ) a[i] = a[i-1] + b[i]; for(int i = 1; i <= n; i ++) cout<<a[i]<<" "; }
二維差分
給定原矩陣a[i,j],構造差分矩陣b[i,j],使得a[][]是b[][]的二維字首和
二維差分核心操作
給以(x1,y1)為左上角,(x2,y2)為右下角的子矩陣中的所有數a[i,j],加上C。
//對於差分陣列的影響:
b[x1,y1] += C;
b[x1,y2+1] -=C;
b[x2+1,y1] -= C;
b[x2+1,y2+1] +=C;
#include<iostream> using namespace std; const int N = 1e3+10; int n,m,q; 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(){ 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 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 ++ ){ a[i][j] = a[i-1][j]+a[i][j-1]-a[i-1][j-1]+b[i][j]; } } for(int i = 1; i <= n; i ++){ for(int j = 1; j <= m; j ++ ){ cout<<a[i][j]<<" "; } puts(""); } }