voidadd(int x, int y, int v){ for (int i = x; i <= n; i += lowbit(i)) { for (int j = y; j <= m; j += lowbit(j)) { c[i][j] += v; } } }
对于子矩阵的查询,先给出查询左上角起点为$(1,1)$的矩阵的和的公式:
1 2 3 4 5 6 7 8 9 10 11
//ask for the submatrix (1,1) -> (x,y) longlongask(int x, int y){ longlong ans = 0; for(int i = x; i > 0; i -= lowbit(i)){ for(int j = y; j > 0; j -= lowbit(j)){ ans += C[i][j]; } }
/** * @brief only for two operations: modify a single point and sum a submatrix * */ structfenwick_2d_1{ int m,n;//size longlong C[MAXM][MAXN];//fenwick tree
fenwick_2d_1(int m_, int n_){ m = m_; n = n_; memset(C, 0, sizeof(C)); }
/** * @brief Modify a single element * * @param x x-index (1-based) * @param y y-index (1-based) * @param val plus val */ voidadd(int x, int y, longlong val){ for(int i = x; i <= m; i += lowbit(i)){ for(int j = y; j < n; j += lowbit(j)){ C[i][j] += val; } } }
//ask for the submatrix (1,1) -> (x,y) longlongask(int x, int y){ longlong ans = 0; for(int i = x; i > 0; i -= lowbit(i)){ for(int j = y; j > 0; j -= lowbit(j)){ ans += C[i][j]; } }
return ans; }
//(p,q) -> (x,y) longlongask_sub(int p, int q, int x, int y){ returnask(x, y)-ask(p - 1, y)-ask(q - 1, y)+ask(p, q); } };
structfenwick_2d_2 { int m, n; longlong C[MAXM][MAXN];//此处维护差分数组 voidinit(int m_, int n_){ m = m_; n = n_; memset(C, 0, sizeof(C)); }
/** * @brief submatrix(1,1) -> (x,y) all add val * * @param x * @param y * @param val * 这里的代码和上一个代码的add完全相同,但是意义不一样,因为这里的C维护的是差分数组 */ voidadd(int x, int y, longlong val){ for(int i = x; i <= m; i += lowbit(i)){ for(int j = y; j <= n; j += lowbit(y)){ C[i][j] += val; } } }
/** * @brief return the value of index (x,y) * * @param x * @param y * @return long long */ longlongask(int x,int y) { longlong ret=0; for(int i = x; i > 0; i -= lowbit(i)){ for(int j = y;j > 0;j -= lowbit(j)){ ret += C[i][j]; } }
//区间修改 /** * @brief Add val for single element (x,y) * * @param x * @param y * @param val */ voidadd(int x, int y, longlong val){ for(int i = x;i <= m;i += lowbit(i)) { for(int j = y;j <= n;j += lowbit(j)) { C1[i][j] += val; C2[i][j] += val * x; C3[i][j] += val * y; C4[i][j] += val * x * y; } } }
/** * @brief Add val for all elements in the submatrix * * @param x * @param y * @param val */ voidadd_submatrix(int x1, int y1, int x2, int y2, longlong val){ add(x1,y1,val); add(x1,y2+1,-val); add(x2+1,y1,-val); add(x2+1,y2+1,val); }
//区间查询 /** * @brief the sum of the submatrix (1,1) -> (x,y) * * @param x * @param y * @return long long */ longlongrangeAsk1(int x, int y){ longlong ans = 0; for(int i = x; i > 0; i -= lowbit(i)){ for(int j = 0; j > 0; j -= lowbit(j)){ ans += (x + 1)*(y + 1)*C1[i][j]; ans -= (y + 1)*C2[i][j] + (x + 1)*C3[i][j]; ans += C4[i][j]; } } return ans; }
longlongrangeAsk2(int x1, int y1, int x2, int y2){ returnrangeAsk1(x2,y2) - rangeAsk1(x1-1,y2) - rangeAsk1(x2,y1-1) + rangeAsk1(x1-1,y1-1); }
//单点查询 longlongask(int x,int y) { returnrangeAsk2(x, y, x, y); }
//单点修改的退化情况 voidmodifySingle(int x, int y, longlong val){ add_submatrix(x, y, x, y, val); } };