树状数组 / 二维树状数组
一维树状数组
· 单点修改 + 单点查询:
直接使用即可
· 区间修改 + 单点查询:
另外维护一个维护前缀和的树状数组,查询时查询与原值相加即可。
· 区间修改 + 区间查询:
若要查询区间$[1, R]$的区间和,可推公式,其中$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)$的出现次数得:
同一维树状数组的区间修改 + 区间查询,维护四个二维树状数组即可。
· 完整代码:
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
树状数组 / 二维树状数组相关推荐
- szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】
树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...
- 二维树状数组 ----2021广东省赛 ----- K - Kera‘s line segment[区间转二维平面+树状数组维护前缀最小最大值]
题目链接 题目大意: 就是一个一维的数轴上面有一堆线段用一个三元组(l,r,val)(l,r,val)(l,r,val)表示. 现在我们有两个操作: 就是往数轴上面添加线段 询问[L,R][L,R][ ...
- 【二维树状数组】See you~
https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/F [题意] 给定一个矩阵,每个格子的初始值为1.现在可以对矩阵有四种操作: A ...
- POJ_1195 Mobile phones 【二维树状数组】
题目链接:http://poj.org/problem?id=1195 纯纯的二维树状数组,不解释,仅仅须要注意一点,由于题目中的数组从0開始计算,所以维护的时候须要加1.由于树状数组的下标是不能为1 ...
- 洛谷1527(bzoj2738)矩阵乘法——二维树状数组+整体二分
题目:https://www.luogu.org/problemnew/show/P1527 不难想到(?)可以用二维树状数组.但维护什么?怎么查询是难点. 因为求第k小,可以考虑记权值树状数组,把比 ...
- 二维树状数组 BZOJ 1452 [JSOI2009]Count
题目链接 裸二维树状数组 #include <bits/stdc++.h>const int N = 305; struct BIT_2D {int c[105][N][N], n, m; ...
- HDU-4456 Crowd 二维树状数组+坐标转换
题意:给定一个N*N的网格,现在M组操作,一种操作时改变网格上的某个单点的权值,另外一种操作是求到一点曼哈顿距离为小于等于k的所有的权值和,初始化网格所有点的权值为0. 解法:这题如果没有那些特定的条 ...
- hdu 1892二维树状数组
这题我知道是用树状数组,可是好久没打树状数组了,就想用普通方法水过去~~结果--结果--水了好多方法都水不过,出题人真狠呐--我的水方法是对于每一次查询,初始化ans=(x2-x1+1)*(y2-y1 ...
- poj 1195(二维树状数组)
解题思路:这是一道很裸的二维树状数组 AC: #include<stdio.h> #include<string.h> #define N 1100 int c[N][N],n ...
最新文章
- 有无符号的整数、二进制
- _ZNote_Qt_定时器的总结
- Ubuntu16.04下创建工作空间并添加自己的功能包(python代码)
- boost::ratio_less_equal相关的测试程序
- 校验功能算eo还是ilf_如何区分ILF和EIF?
- 动手学PaddlePaddle(3):猫脸识别
- 在Blazor中构建数据库应用程序——第5部分——查看组件——UI中的CRUD列表操作
- 操作系统思考 第一章 编译
- 'pip' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
- `node2vec` `TSNE` 待解决问题
- 两个tplink路由器有线桥接_如何装2个tplink无线路由器_两个tplink路由器怎么设置?-192路由网...
- Apache DolphinScheduler 3.0.0 正式版发布!
- 脚本之家去广告JS插件
- 在android tegra2中添加一个camera
- 联想thinkpad E450C如何进入BIOS?
- 数据结构与算法——RB树简介
- 常用于应届生面试的24道面试题
- vue项目中使用天地图
- 【知识蒸馏】Masked Generative Distillation
- Android中对付ANR的N种武器
热门文章
- 2017.7.10 Redis报错:DENIED Redis is running in protected mode
- 网站压力测试工具webbench 安装与使用
- 经典算法系列三----堆排序
- linux下mysql-5.5.15安装详细步骤
- Enterprise Solution 解决方案与源代码下载
- UICollectionView 应用
- (转)Android中JNI编程的那些事儿
- Leetcode-1156 Swap For Maximum Repeated Substring(单字符重复子串的最大长度)
- qmake生成VS的vcproj/sln工程文件
- java类与对象(属性,方法)的使用