一维树状数组

· 单点修改 + 单点查询:

  直接使用即可

· 区间修改 + 单点查询:

  另外维护一个维护前缀和的树状数组,查询时查询与原值相加即可。

· 区间修改 + 区间查询:

  若要查询区间$[1, R]$的区间和,可推公式,其中$D[i]$表示差分数组:

$\sum\limits_{i=1}^R \sum\limits_{j=1}^i D[j]$
$= \sum\limits_{i=1}^R (R - i + 1) * D[i]$
$= (x + 1) \sum\limits_{i=1}^R D[i] -  \sum\limits_{i=1}^R (i * D[i])$

  此时维护$\sum D[i]$及$\sum (i * D[i])$就好了。

二维树状数组

· 单点修改 + 单点查询:

  二维树状数组就是在一维的基础上维护一个矩阵,直接维护即可。

· 区间修改 + 单点查询:

  由$Sum[i][j] = Sum[i - 1][j] + Sum[i][j - 1] - Sum[i - 1][j - 1] + a[i][j]$得到启发,可以维护形似$a[i][j] -> a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1]$的差分数组,加如下代码即可:

void Add_Main (int x1, int y1, int x2, int y2, int delta) {Add (x1, y1, delta);Add (x2 + 1, y1, - delta);Add (x1, y2 + 1, - delta);Add (x2 + 1, y2 + 1, delta);
}

· 区间修改 + 区间查询:

  推公式,可以由每个二元组$(x, y)$的出现次数得:

$\sum\limits_{x=1}^n\sum\limits_{y=1}^m\sum\limits_{i=1}^x\sum\limits_{j=1}^yD[i][j]$
$= \sum\limits_{x=1}^n\sum\limits_{y=1}^m D[x][y] (n - x + 1) (m - y + 1)$
$= \sum\limits_{x=1}^n\sum\limits_{y=1}^m (D[x][y] (n + 1) (m + 1) - D[x][y] (n + 1) * y - D[x][y] (m + 1) * x + D[x][y] * x * y)$

  同一维树状数组的区间修改 + 区间查询,维护四个二维树状数组即可。

· 完整代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4
  5 using namespace std;
  6
  7 typedef long long LL;
  8
  9 const int MAXN = 2048 + 10;
 10
 11 int N, M;
 12
 13 char opt[5];
 14
 15 int lowbit (int x) {
 16     return x & (- x);
 17 }
 18
 19 int Tree1[MAXN][MAXN]= {0};
 20 int Tree2[MAXN][MAXN]= {0};
 21 int Tree3[MAXN][MAXN]= {0};
 22 int Tree4[MAXN][MAXN]= {0};
 23
 24 void Add (int x, int y, int delta) {
 25     int tx = x, ty = y;
 26     while (x <= N) {
 27         y = ty;
 28         while (y <= M) {
 29             Tree1[x][y] += delta;
 30             Tree2[x][y] += ty * delta;
 31             Tree3[x][y] += tx * delta;
 32             Tree4[x][y] += tx * ty * delta;
 33             y += lowbit (y);
 34         }
 35         x += lowbit (x);
 36     }
 37 }
 38
 39 void Add_Main (int x1, int y1, int x2, int y2, int delta) {
 40     Add (x1, y1, delta);
 41     Add (x2 + 1, y1, - delta);
 42     Add (x1, y2 + 1, - delta);
 43     Add (x2 + 1, y2 + 1, delta);
 44 }
 45
 46 int Query (int x, int y) {
 47     int tx = x, ty = y;
 48     int cnt = 0;
 49     while (x >= 1) {
 50         y = ty;
 51         while (y >= 1) {
 52             cnt += (tx + 1) * (ty + 1) * Tree1[x][y];
 53             cnt -= (tx + 1) * Tree2[x][y];
 54             cnt -= (ty + 1) * Tree3[x][y];
 55             cnt += Tree4[x][y];
 56             y -= lowbit (y);
 57         }
 58         x -= lowbit (x);
 59     }
 60
 61     return cnt;
 62 }
 63
 64 int Query_Main (int x1, int y1, int x2, int y2) {
 65     return Query (x2, y2) - Query (x2, y1 - 1) - Query (x1 - 1, y2) + Query (x1 - 1, y1 - 1);
 66 }
 67
 68 int getnum () {
 69     int num = 0;
 70     char ch = getchar ();
 71     int flag = 0;
 72
 73     while (! isdigit (ch)) {
 74         if (ch == '-')
 75             flag = 1;
 76         ch = getchar ();
 77     }
 78     while (isdigit (ch))
 79         num = (num << 3) + (num << 1) + ch - '0', ch = getchar ();
 80
 81     return flag ? - num : num;
 82 }
 83
 84 int main () {
 85     scanf ("%s", opt + 1);
 86     N = getnum (), M = getnum ();
 87
 88     while (~ scanf ("%s", opt + 1)) {
 89         if (opt[1] == 'L') {
 90             int x1, y1, x2, y2;
 91             int delta;
 92             x1 = getnum (), y1 = getnum (), x2 = getnum (), y2 = getnum ();
 93             delta = getnum ();
 94
 95             Add_Main (x1, y1, x2, y2, delta);
 96         }
 97         else {
 98             int x1, y1, x2, y2;
 99             x1 = getnum (), y1 = getnum (), x2 = getnum (), y2 = getnum ();
100
101             int ans = Query_Main (x1, y1, x2, y2);
102             printf ("%d\n", ans);
103         }
104     }
105
106     return 0;
107 }
108
109 /*
110 X 4 4
111 L 1 1 3 3 2
112 L 2 2 4 4 1
113 k 2 2 3 3
114 */

二维树状数组(区间修改 + 区间查询)

转载于:https://www.cnblogs.com/Colythme/p/9853159.html

树状数组 / 二维树状数组相关推荐

  1. szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】

    树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...

  2. 二维树状数组 ----2021广东省赛 ----- K - Kera‘s line segment[区间转二维平面+树状数组维护前缀最小最大值]

    题目链接 题目大意: 就是一个一维的数轴上面有一堆线段用一个三元组(l,r,val)(l,r,val)(l,r,val)表示. 现在我们有两个操作: 就是往数轴上面添加线段 询问[L,R][L,R][ ...

  3. 【二维树状数组】See you~

    https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/F [题意] 给定一个矩阵,每个格子的初始值为1.现在可以对矩阵有四种操作: A ...

  4. POJ_1195 Mobile phones 【二维树状数组】

    题目链接:http://poj.org/problem?id=1195 纯纯的二维树状数组,不解释,仅仅须要注意一点,由于题目中的数组从0開始计算,所以维护的时候须要加1.由于树状数组的下标是不能为1 ...

  5. 洛谷1527(bzoj2738)矩阵乘法——二维树状数组+整体二分

    题目:https://www.luogu.org/problemnew/show/P1527 不难想到(?)可以用二维树状数组.但维护什么?怎么查询是难点. 因为求第k小,可以考虑记权值树状数组,把比 ...

  6. 二维树状数组 BZOJ 1452 [JSOI2009]Count

    题目链接 裸二维树状数组 #include <bits/stdc++.h>const int N = 305; struct BIT_2D {int c[105][N][N], n, m; ...

  7. HDU-4456 Crowd 二维树状数组+坐标转换

    题意:给定一个N*N的网格,现在M组操作,一种操作时改变网格上的某个单点的权值,另外一种操作是求到一点曼哈顿距离为小于等于k的所有的权值和,初始化网格所有点的权值为0. 解法:这题如果没有那些特定的条 ...

  8. hdu 1892二维树状数组

    这题我知道是用树状数组,可是好久没打树状数组了,就想用普通方法水过去~~结果--结果--水了好多方法都水不过,出题人真狠呐--我的水方法是对于每一次查询,初始化ans=(x2-x1+1)*(y2-y1 ...

  9. poj 1195(二维树状数组)

    解题思路:这是一道很裸的二维树状数组 AC: #include<stdio.h> #include<string.h> #define N 1100 int c[N][N],n ...

最新文章

  1. 有无符号的整数、二进制
  2. _ZNote_Qt_定时器的总结
  3. Ubuntu16.04下创建工作空间并添加自己的功能包(python代码)
  4. boost::ratio_less_equal相关的测试程序
  5. 校验功能算eo还是ilf_如何区分ILF和EIF?
  6. 动手学PaddlePaddle(3):猫脸识别
  7. 在Blazor中构建数据库应用程序——第5部分——查看组件——UI中的CRUD列表操作
  8. 操作系统思考 第一章 编译
  9. 'pip' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
  10. `node2vec` `TSNE` 待解决问题
  11. 两个tplink路由器有线桥接_如何装2个tplink无线路由器_两个tplink路由器怎么设置?-192路由网...
  12. Apache DolphinScheduler 3.0.0 正式版发布!
  13. 脚本之家去广告JS插件
  14. 在android tegra2中添加一个camera
  15. 联想thinkpad E450C如何进入BIOS?
  16. 数据结构与算法——RB树简介
  17. 常用于应届生面试的24道面试题
  18. vue项目中使用天地图
  19. 【知识蒸馏】Masked Generative Distillation
  20. Android中对付ANR的N种武器

热门文章

  1. 2017.7.10 Redis报错:DENIED Redis is running in protected mode
  2. 网站压力测试工具webbench 安装与使用
  3. 经典算法系列三----堆排序
  4. linux下mysql-5.5.15安装详细步骤
  5. Enterprise Solution 解决方案与源代码下载
  6. UICollectionView 应用
  7. (转)Android中JNI编程的那些事儿
  8. Leetcode-1156 Swap For Maximum Repeated Substring(单字符重复子串的最大长度)
  9. qmake生成VS的vcproj/sln工程文件
  10. java类与对象(属性,方法)的使用