三百行代码演绎树状数组基础全家桶(一维树状数组 + 二维树状数组)
/* #include<map> #include<cmath> #include<queue> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; template<class T> inline void read(T &x){ x = 0; register char c = getchar(); register bool f = 0; while(!isdigit(c)) f ^= c == '-', c = getchar(); while(isdigit(c)) x = x * 10 + c - '0', c = getchar(); if(f) x = -x; } template<class T> inline void print(T x){ if(x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar('0' + x % 10); } */ /*单点修改,区间查询 const int N = 5e5 + 10; int n, m; int a[N], tree[N]; inline int lowbit(int x){ return x & -x; } inline void update(int x, int v){ for(; x <= n; x += lowbit(x)){ tree[x] += v; } } inline int query(int x){ int res = 0; for(; x; x -= lowbit(x)){ res += tree[x]; } return res; } int main(){ read(n), read(m); for(int i = 1; i <= n; i ++) read(a[i]), update(i, a[i]); for(int i = 1, opt, x, y; i <= m; i ++){ read(opt); if(opt == 1){ read(x), read(y); update(x, y); }else if(opt == 2){ read(x), read(y); print(query(y) - query(x - 1)); puts(""); } } return 0; } */ /*区间修改,单点查询 #define int long long const int N = 1e6 + 10; int n, m; int a[N], tree[N]; inline int lowbit(int x){ return x & -x; } inline void update(int x, int v){ for(; x <= n; x += lowbit(x)){ tree[x] += v; } } inline int query(int x){ int res = 0; for(; x; x -= lowbit(x)){ res += tree[x]; } return res; } signed main(){ read(n), read(m); for(int i = 1; i <= n; i ++){ read(a[i]); } update(1, a[1]); for(int i = 2; i <= n; i ++){ update(i, a[i] - a[i - 1]); } for(int i = 1, opt, a, b, c; i <= m; i ++){ read(opt); if(opt == 1){ read(a), read(b), read(c); update(a, c), update(b + 1, -c); }else if(opt == 2){ read(a); print(query(a)); puts(""); } } return 0; }*/ /*区间查询,区间修改 #define int long long const int N = 1e6 + 10; int n, m, a[N]; int tree1[N], tree2[N]; inline int lowbit(int x){ return x & -x; } inline void update(int x, int v){ int p = x; for(; x <= n; x += lowbit(x)){ tree1[x] += v, tree2[x] += v * p; } } inline void range_update(int l, int r, int v){ update(l, v), update(r + 1, -v); } inline int query(int x){ int res = 0, p = x; for(; x; x -= lowbit(x)){ res += (p + 1) * tree1[x] - tree2[x]; } return res; } inline int range_query(int l, int r){ return query(r) - query(l - 1); } signed main(){ read(n), read(m); for(int i = 1; i <= n; i ++) read(a[i]); for(int i = 1; i <= n; i ++) update(i, a[i] - a[i - 1]); for(int i = 1, opt, a, b, c; i <= m; i ++){ read(opt); if(opt == 1){ read(a), read(b), read(c); range_update(a, b, c); }else if(opt == 2){ read(a), read(b); print(range_query(a, b)); puts(""); } } return 0; }*/ /************************************************************************************ 接下来是二维树状数组 一维树状数组中,tree[x]:右端点为x,长度为lowbit(x)的区间的区间和。 二维树状数组中,tree[x][y]:右下角为(x, y),高为lowbit(x),宽为 lowbit(y)的区间的区间和。 ************************************************************************************/ //单点修改,区间查询 /*inline void update(int x, int y, int v){//将点(x, y)加上 z int memo_y = y; while(x <= n){ y = memo_y; while(y <= n){ tree[x][y] += v, y += lowbit(y); } x += lowbit(x); } } inline void query(int x, int y){//求左上角为(1, 1)右下角为(x, y)的矩阵和 int res = 0, memo_y = y; while(x){ y = memo_y; while(y){ res += tree[x][y], y -= lowbit(y); } x -= lowbit(x); } }*/ //区间修改,单点查询 /*inline void update(int x, int y, int v){ int memo_y = y; while(x <= n){ y = memo_y; while(y <= n){ tree[x][y] += v, y += lowbit(y); } x += lowbit(x); } } inline void range_update(int x1, int y1, int x2, int y2, int v){ update(x1, y1, v); update(x1, y2 + 1, -v); update(x2 + 1, y1, -v); update(x2 + 1, y2 + 1, v); } inline void query(int x, int y){ int res = 0, memo_y = y; while(x){ y = memo_y; while(y) res += tree[x][y], y -= lowbit(y); } x -= lowbit(x); }*/ //重点————区间修改,区间查询 //P4514 上帝造题的七分钟 #include<map> #include<cmath> #include<queue> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; template<class T> inline void read(T &x){ x = 0; register char c = getchar(); register bool f = 0; while(!isdigit(c)) f ^= c == '-', c = getchar(); while(isdigit(c)) x = x * 10 + c - '0', c = getchar(); if(f) x = -x; } template<class T> inline void print(T x){ if(x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar('0' + x % 10); } inline char readc(){ char ch; while(ch = getchar(), ch != EOF && !isalpha(ch)); return ch; } const int N = 2049; int n, m; char c; int tree[4][N][N]; inline int lowbit(int x){ return x & -x; } inline void update(int x, int y, int v){ if(x < 1 || n < x || y < 1 || m < y) return; for(int i = x; i <= n; i += lowbit(i)){ for(int j = y; j <= m; j += lowbit(j)){ tree[0][i][j] += v; tree[1][i][j] += v * x; tree[2][i][j] += v * y; tree[3][i][j] += v * x * y; } } } inline void range_update(int x1, int y1, int x2, int y2, int v){ update(x1, y1, v); update(x1, y2 + 1, -v); update(x2 + 1, y1, -v); update(x2 + 1, y2 + 1, v); } inline int query(int x, int y){ int res = 0; for(int i = x; i; i -= lowbit(i)){ for(int j = y; j; j -= lowbit(j)){ res += (x + 1) * (y + 1) * tree[0][i][j] - (y + 1) * tree[1][i][j] - (x + 1) * tree[2][i][j] + tree[3][i][j]; } } return res; } inline int range_query(int x1, int y1, int x2, int y2){ return query(x2, y2) - query(x2, y1 - 1) - query(x1 - 1, y2) + query(x1 - 1, y1 - 1); } signed main(){ /*read(n), read(m), read(Q); for(int i = 1; i <= n; i ++){ for(int j = 1; j <= n; j ++){ int z; read(z); range_update(i, j, i, j, z); } } while(Q --){ int y1, x1, y2, x2, z, a; read(y1), read(x1), read(y2), read(x2), read(z), read(a); if(range_query(x1, y1, x2, y1) < z * (x2 - x1 + 1) * (y2 - y1 + 1)) range_update(x1, y1, x2, y2, a); } for(int i = 1; i <= n; i ++){ for(int j = 1; j <= m; j ++) print(range_query(i, j, i, j)); cout << " "; puts(""); } return 0;*/ readc(); read(n), read(m); int x1, x2, y1, y2, v; while(c = readc(), c != EOF){ read(x1), read(y1), read(x2), read(y2); if(c == 'L'){ read(v); range_update(x1, y1, x2, y2, v); }else if(c == 'k'){ print(range_query(x1, y1, x2, y2)); puts(""); } } return 0; }