二维线段树和二维树状数组
2016-04-01 12:22
393 查看
二维线段树,支持单点更新、元素求和、查询最大值和最小值。
代码:
二维树状数组,支持单点更新、求和。
代码:
代码:
struct Nodey { int ly, ry, val, Max, Min, sum;//元素 最大值 最小值 元素和 }; int nx, ny;//横长 竖长 int posx[MAXN], posy[MAXN]; struct Nodex { int lx, rx; Nodey treey[MAXN<<2]; void Build_y(int o, int l, int r) { treey[o].ly = l; treey[o].ry = r; treey[o].Max = 0; treey[o].Min = INF; treey[o].sum = 0; treey[o].val = 0; if(l == r) { posy[l] = o; return ; } int mid = (l + r) >> 1; Build_y(ll, l, mid); Build_y(rr, mid+1, r); } int Query_y(int o, int y1, int y2, int op) { if(treey[o].ly == y1 && treey[o].ry == y2) { if(op == 0) return treey[o].Max; if(op == 1) return treey[o].Min; if(op == 2) return treey[o].sum; } int mid = (treey[o].ly + treey[o].ry) >> 1; if(y2 <= mid) return Query_y(ll, y1, y2, op); else if(y1 > mid) return Query_y(rr, y1, y2, op); else { if(op == 0) return max(Query_y(ll, y1, mid, op), Query_y(rr, mid+1, y2, op)); if(op == 1) return min(Query_y(ll, y1, mid, op), Query_y(rr, mid+1, y2, op)); if(op == 2) return Query_y(ll, y1, mid, op) + Query_y(rr, mid+1, y2, op); } } }; Nodex treex[MAXN<<2]; void Build_x(int o, int l, int r) { treex[o].lx = l; treex[o].rx = r; treex[o].Build_y(1, 1, ny); if(l == r) { posx[l] = o; return ; } int mid = (l + r) >> 1; Build_x(ll, l, mid); Build_x(rr, mid+1, r); } int Query_x(int o, int x1, int x2, int y1, int y2, int op) { if(treex[o].lx == x1 && treex[o].rx == x2) { return treex[o].Query_y(1, y1, y2, op); } int mid = (treex[o].lx + treex[o].rx) >> 1; if(x2 <= mid) return Query_x(ll, x1, x2, y1, y2, op); else if(x1 > mid) return Query_x(rr, x1, x2, y1, y2, op); else { if(op == 0) return max(Query_x(ll, x1, mid, y1, y2, op), Query_x(rr, mid+1, x2, y1, y2, op)); if(op == 1) return min(Query_x(ll, x1, mid, y1, y2, op), Query_x(rr, mid+1, x2, y1, y2, op)); if(op == 2) return Query_x(ll, x1, mid, y1, y2, op) + Query_x(rr, mid+1, x2, y1, y2, op); } } void PushUpy(int x, int y) { treex[x].treey[y].Max = max(treex[x].treey[y<<1].Max, treex[x].treey[y<<1|1].Max); treex[x].treey[y].Min = min(treex[x].treey[y<<1].Min, treex[x].treey[y<<1|1].Min); treex[x].treey[y].sum = treex[x].treey[y<<1].sum + treex[x].treey[y<<1|1].sum; } void PushUpx(int x, int y) { treex[x].treey[y].Max = max(treex[x<<1].treey[y].Max, treex[x<<1|1].treey[y].Max); treex[x].treey[y].Min = min(treex[x<<1].treey[y].Min, treex[x<<1|1].treey[y].Min); treex[x].treey[y].sum = treex[x<<1].treey[y].sum + treex[x<<1|1].treey[y].sum; } void Change(int x, int y, int v) { treex[x].treey[y].Max = v; treex[x].treey[y].Min = v; treex[x].treey[y].sum = v; treex[x].treey[y].val = v; } void Update(int x, int y, int v) {//单点更新 for(int i = posx[x]; i ; i >>= 1) { for(int j = posy[y]; j ; j >>= 1) { if(i == posx[x] && j == posy[y]) { Change(posx[x], posy[y], v); continue; } PushUpy(i, j); } if(i == posx[x]) continue; for(int j = posy[y]; j ; j >>= 1) { PushUpx(i, j); } } } int Sum(int x, int y) {//求 (x, y)对应节点到根路径的元素之和 int sum = 0; for(int i = posx[x]; i ; i >>= 1) { for(int j = posy[y]; j ; j >>= 1) { sum += treex[i].treey[j].val; } } return sum; }
二维树状数组,支持单点更新、求和。
代码:
int C[MAXN][MAXN]; int nx, ny; int lowbit(int x) { return x & (-x); } void add(int x, int y, int d) { while(x <= nx) { int sy = y; while(sy <= ny) { C[x][sy] += d; sy += lowbit(sy); } x += lowbit(x); } } int Sum(int x, int y) { int s = 0; while(x > 0) { int sy = y; while(sy > 0) { s += C[x][sy]; sy -= lowbit(sy); } x -= lowbit(x); } return s; }
相关文章推荐
- HDU-1584-蜘蛛牌
- JZOJ 3104【NOIP2012提高组】疫情控制
- ViewPager轮播下加小圆点
- SVM多类划分问题 one vs rest
- 课程练习一Problem M
- 多态之实现模拟虚表
- 获取SD卡中的音乐文件
- 各种正则表达式验证
- ajax
- Dota2APP--第二天
- HDU-1312-Red and Black
- HDU-1241-Oil Deposits
- VS2015 + opencv3.1 环境配置记录
- Bluetooth4.3 读取特征字值的问题
- iOS didReceiveMemoryWarining
- HTML5中div section article的区别
- When Should You Override viewDidLayoutSubviews?
- hdu oj题分类
- Codeforces Round #346 (Div. 2)E. New Reform 乱搞dfs
- WebView