二维线段树,就是在一维线段树的基础上,把每个区间节点换成了另一颗线段树而已
也就是树中套树
每个节点访问的时候,都要对第二颗树进行一次查询,每次查询O(logY)
对于第一棵树查询要查询第二棵树logX次,故总的复杂度是O(logX * logY)
#include<cstdio> #include<cmath> #include<cstring> #include<queue> #include<vector> #include<functional> #include<algorithm> using namespace std; typedef long long LL; const int MX = 1000 + 5; const int INF = 0x3f3f3f3f; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define root 1,n,1 int T, n, m; char SUM[MX << 2][MX << 2]; void build() { memset(SUM, 0, sizeof(SUM)); } void update_y(int xrt, int L, int R, int l, int r, int rt) { if(L <= l && r <= R) { SUM[xrt][rt] = (SUM[xrt][rt] + 1) % 2; return; } int m = (l + r) >> 1; if(L <= m) update_y(xrt, L, R, lson); if(R > m) update_y(xrt, L, R, rson); } void update_x(int xL, int xR, int yL, int yR, int l, int r, int rt) { if(xL <= l && r <= xR) { update_y(rt, yL, yR, root); return; } int m = (l + r) >> 1; if(xL <= m) update_x(xL, xR, yL, yR, lson); if(xR > m) update_x(xL, xR, yL, yR, rson); } int query_y(int xrt, int y, int l, int r, int rt) { if(l == r) { return SUM[xrt][rt]; } int m = (l + r) >> 1, ret = SUM[xrt][rt]; if(y <= m) ret += query_y(xrt, y, lson); else ret += query_y(xrt, y, rson); return ret % 2; } int query_x(int x, int y, int l, int r, int rt) { if(l == r) { return query_y(rt, y, root); } int m = (l + r) >> 1, ret = query_y(rt, y, root); if(x <= m) ret += query_x(x, y, lson); else ret += query_x(x, y, rson); return ret % 2; } int main() { scanf("%d", &T); bool first = true; while(T--) { build(); scanf("%d%d", &n, &m); if(first) first = false; else puts(""); for(int i = 1; i <= m; i++) { char op[10]; int a, b, c, d; scanf("%s", op); if(op[0] == 'C') { scanf("%d%d%d%d", &a, &c, &b, &d); update_x(a, b, c, d, root); } else { scanf("%d%d", &a, &b); printf("%d\n", query_x(a, b, root)); } } } return 0; }