[ifrog 1069 Rectangle Cover] 二维树状数组
知识点:tree
2-D Binary Indexed Tree
1. 题目链接
2. 题意描述
有一个 n∗n 的区域,在这个区域进行两种操作,总共操作 q 次。
- 操作一: 以
(x1,y1) 为左上点, (x2,y2) 为右下点,画一个矩形;- 操作二:求点 (x,y) 上有多少个矩形覆盖。
数据范围: 1≤n≤103,q≤50000 。
3. 解题思路
赤裸裸的二维树状数组。区间覆盖的时候需要维护四个点: (x1,y1),(x2+1,y1),(x1,y2+1),(x2+1,y2+1) 。
4. 实现代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; const int MAXN = 1000 + 5; const int INF = 0x3f3f3f3f; const LL INFL = 0x3f3f3f3f3f3f3f3fLL; int n, q; LL c[MAXN][MAXN]; inline int lowbit(const int& x) { return x & (-x); } void add(int x, int yz, int v) { while(x <= n) { int y = yz; while(y <= n) { c[x][y] += v; y += lowbit(y); } x += lowbit(x); } } LL query(int x, int yz) { LL ret = 0; while(x > 0) { int y = yz; while(y > 0) { ret += c[x][y]; y -= lowbit(y); } x -= lowbit(x); } return ret; } int main() { #ifdef ___LOCAL_WONZY___ freopen("input.txt", "r", stdin); #endif // ___LOCAL_WONZY___ int _, cas = 0; scanf("%d", &_); char op[5]; int x[3], y[3]; while(_ --) { if(cas) printf("\n"); ++ cas; memset(c, 0, sizeof(c)); scanf("%d %d", &n, &q); while(q --) { scanf("%s", op); if(op[0] == 'Q') { scanf("%d %d", x, y); printf("%lld\n", query(x[0], y[0])); } else { scanf("%d %d %d %d", x + 1, y + 1, x + 2, y + 2); add(x[1], y[1], 1); add(x[2] + 1, y[2] + 1, 1); add(x[1], y[2] + 1, -1); add(x[2] + 1, y[1], -1); } } } return 0; }