二维线段树之树套树
Posted daybreaking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二维线段树之树套树相关的知识,希望对你有一定的参考价值。
1 //poj1195 二维线段树之树套树 2 // 先确定横坐标所在的区间并记录该结点的编号p,然后再确定纵坐标所在的区间并记录该结点的编号cur,则tree[cur][p]为目标区间。 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cmath> 7 #include <algorithm> 8 #include <queue> 9 #include <stack> 10 #include <deque> 11 #include <map> 12 #include <iostream> 13 using namespace std; 14 typedef long long LL; 15 const double pi = acos(-1.0); 16 const double e = exp(1); 17 //const int MAXN =2e5+10; 18 const int N = 1055; 19 20 //const int maxn = 1024 * 1024 * 1.5; 21 22 int n; 23 int sum[N * 3][N * 3]; 24 25 void updatey(int y, int l, int r, int cur, int p, int op, int val) 26 // 纵坐标目标值,待找区间的左端点,待找区间的右端点,y中树的结点的下标,已找到的横坐标中结点的下标,值更新的方式,需要更新的值 27 { 28 if(l == r) 29 { 30 if(op == 1) //根据题目要求,对目标值直接修改 31 { 32 sum[p][cur] += val; 33 } 34 else // 回溯过程中,维护树的结构 35 { 36 sum[p][cur] = sum[p << 1][cur] + sum[p << 1 | 1][cur]; 37 } 38 return ; 39 } 40 int mid = (l + r) >> 1; 41 if(y <= mid) //当前结点的左孩子区间需要找 42 { 43 updatey(y, l, mid, cur << 1, p, op, val); 44 } 45 else // 当前结点的右孩子区间需要找 46 { 47 updatey(y, mid + 1, r, cur << 1 | 1, p, op, val); 48 } 49 sum[p][cur] = sum[p][cur << 1] + sum[p][cur << 1 | 1]; 50 51 } 52 53 void updatex(int x, int y, int l, int r, int cur, int val) 54 { 55 if(l == r) 56 { 57 updatey(y, 1, n, 1, cur, 1, val); //锁定了横坐标所在的结点cur,再去寻找纵坐标所在的结点。 58 return ; 59 } 60 int mid = (l + r) >> 1; 61 if(x <= mid) 62 { 63 updatex(x, y, l, mid, cur << 1, val); 64 } 65 else 66 { 67 updatex(x, y, mid + 1, r, cur << 1 | 1, val); 68 } 69 updatey(y, 1, n, 1, cur, 2, val); 70 } 71 72 int queryy(int ly, int ry, int l, int r, int cur, int p) 73 { 74 if(ly <= l && ry >= r) 75 { 76 return sum[p][cur]; 77 } 78 int res = 0; 79 int mid = (l + r) >> 1; 80 if(ly <= mid) 81 { 82 res += queryy(ly, ry, l, mid, cur << 1, p); 83 } 84 if(ry > mid) 85 { 86 res += queryy(ly, ry, mid + 1, r, cur << 1 | 1, p); 87 } 88 return res; 89 } 90 91 int queryx(int lx, int rx, int ly, int ry, int l, int r, int cur) 92 { 93 int res = 0; 94 if(lx <= l && rx >= r) 95 { 96 res = queryy(ly, ry, 1, n, 1, cur); 97 return res; 98 } 99 int mid = (l + r) >> 1; 100 if(lx <= mid) 101 { 102 res += queryx(lx, rx, ly, ry, l, mid, cur << 1); 103 } 104 if(rx > mid) 105 { 106 res += queryx(lx, rx, ly, ry, mid + 1, r, cur << 1 | 1); 107 } 108 return res; 109 } 110 111 112 int main() 113 { 114 int i, j, t; 115 int x1, y1, x2, y2, c; 116 117 while(scanf("%d",&t) != EOF) 118 { 119 if(t == 3) 120 break; 121 if(t == 0) 122 { 123 scanf("%d",&n); 124 n ++; 125 memset(sum, 0, sizeof(sum)); 126 } 127 else if(t == 1) 128 { 129 scanf("%d%d%d", &x1, &y1, &c); 130 x1 ++, y1 ++; 131 updatex(x1, y1, 1, n, 1, c); 132 } 133 else if(t == 2) 134 { 135 scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 136 x1++, y1++, x2++, y2++; 137 printf("%d ", queryx(x1, x2, y1, y2, 1, n, 1)); 138 } 139 } 140 141 return 0; 142 }
以上是关于二维线段树之树套树的主要内容,如果未能解决你的问题,请参考以下文章