CodeChef - QRECT Rectangle Query CDQ分治
题解:现在需要维护的每次的询问矩形和前面插入的所有矩形有公共部分的个数。 我们试着直接去维护这个东西, 发现可能的情况太多,不好维护,所以我们维护每次询问的时候在当前矩阵个数下,有多少个矩阵是一定在外面的。对于一个矩阵来说, 我们只需要统计到目前位置, 多少个矩形的下底线 在询问矩形的上底线之上, 这样我们就减去了在询问矩形上方的不重合矩形。 然后我们对矩形的左右下也一样维护这个信息。对于这个操作我们可以用4个树状数组直接去维护这个信息。每个数状数组记录一下每条底线出现的位置。
维护完这个东西之后,我们发现如果一个矩形在询问矩形的左上方, 他会被减去2次,这样就多减了, 我们需要把左上角的矩形个数再加回去。 我们需要 对每个询问矩形来说, 维护出有多少个插入矩形的右下角的端点是在询问矩形的左上角的端点的左上角, 对于这个问题就变成了一个2维偏序问题,我们用cdq去维护这个信息。当然还有其他3个角落,我们也需要对那些角度做一样的操作。最后我们就可以得到答案了。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); 4 #define LL long long 5 #define ULL unsigned LL 6 #define fi first 7 #define se second 8 #define pb push_back 9 #define lson l,m,rt<<1 10 #define rson m+1,r,rt<<1|1 11 #define lch(x) tr[x].son[0] 12 #define rch(x) tr[x].son[1] 13 #define max3(a,b,c) max(a,max(b,c)) 14 #define min3(a,b,c) min(a,min(b,c)) 15 typedef pair<int,int> pll; 16 const int inf = 0x3f3f3f3f; 17 const LL INF = 0x3f3f3f3f3f3f3f3f; 18 const LL mod = (int)1e9+7; 19 const int N = 2e5 + 100; 20 struct Node{ 21 int x1, y1, x2, y2, op, id; 22 }A[N], B[N]; 23 int xsz, ysz; 24 int x[N], y[N]; 25 int tmp[N]; 26 int ans[N]; 27 char s[10]; 28 struct bit_tree{ 29 int tree[N], tot; 30 void add(int x, int v){ 31 for(int i = x; i < N; i += i & (-i)){ 32 tree[i] += v; 33 } 34 tot += v; 35 } 36 int query(int x){ 37 int ret = 0; 38 for(int i = x; i > 0; i -= i & (-i)){ 39 ret += tree[i]; 40 } 41 return ret; 42 } 43 void Clear(){ 44 tot = 0; 45 memset(tree, 0, sizeof(tree)); 46 } 47 }bit[4]; 48 bool cmp1(Node & a, Node & b){ 49 int aop = abs(a.op), bop = abs(b.op); 50 int ax, bx; 51 if(aop) ax = a.x2; 52 else ax = a.x1; 53 if(bop) bx = b.x2; 54 else bx = b.x1; 55 if(ax != bx) return ax < bx; 56 return aop < bop; 57 } 58 bool cmp2(Node & a, Node & b){ 59 int aop = abs(a.op), bop = abs(b.op); 60 int ax, bx; 61 if(!aop) ax = a.x2; 62 else ax = a.x1; 63 if(!bop) bx = b.x2; 64 else bx = b.x1; 65 if(ax != bx) return ax > bx; 66 return aop < bop; 67 } 68 void cdq(int l, int r){ 69 if(l >= r) return ; 70 int mid = l+r >> 1; 71 cdq(l, mid); 72 cdq(mid+1, r); 73 int top = 0; 74 for(int i = l; i <= mid; i++) 75 if(A[i].op) B[++top] = A[i]; 76 for(int i = mid+1; i <= r; i++) 77 if(!A[i].op) B[++top] = A[i]; 78 sort(B+1, B+1+top, cmp1); 79 for(int i = 1; i <= top; i++){ 80 if(B[i].op) { 81 bit[0].add(B[i].y1, B[i].op); 82 bit[1].add(B[i].y2, B[i].op); 83 } 84 else { 85 ans[B[i].id] += bit[0].tot - bit[0].query(B[i].y2); 86 ans[B[i].id] += bit[1].query(B[i].y1-1); 87 } 88 } 89 for(int i = 1; i <= top; i++){ 90 if(B[i].op) { 91 bit[0].add(B[i].y1, -B[i].op); 92 bit[1].add(B[i].y2, -B[i].op); 93 } 94 } 95 sort(B+1, B+1+top, cmp2); 96 for(int i = 1; i <= top; i++){ 97 if(B[i].op) { 98 bit[0].add(B[i].y1, B[i].op); 99 bit[1].add(B[i].y2, B[i].op); 100 } 101 else { 102 ans[B[i].id] += bit[0].tot - bit[0].query(B[i].y2); 103 ans[B[i].id] += bit[1].query(B[i].y1-1); 104 } 105 } 106 for(int i = 1; i <= top; i++){ 107 if(B[i].op) { 108 bit[0].add(B[i].y1, -B[i].op); 109 bit[1].add(B[i].y2, -B[i].op); 110 } 111 } 112 } 113 int main(){ 114 int n; 115 scanf("%d", &n); 116 int t = 0, tt = 0, num = 0, z; 117 for(int i = 1; i <= n; ++i){ 118 scanf("%s", s); 119 if(s[0] == 'I'){ 120 num++; 121 scanf("%d%d%d%d", &A[i].x1, &A[i].y1, &A[i].x2, &A[i].y2); 122 x[++xsz] = A[i].x1; x[++xsz] = A[i].x2; 123 y[++ysz] = A[i].y1; y[++ysz] = A[i].y2; 124 A[i].op = 1; 125 tmp[++t] = i; 126 } 127 else if(s[0] == 'D'){ 128 num--; 129 scanf("%d", &z); 130 A[i] = A[tmp[z]]; 131 A[i].op = -1; 132 } 133 else { 134 ++tt; 135 scanf("%d%d%d%d", &A[i].x1, &A[i].y1, &A[i].x2, &A[i].y2); 136 x[++xsz] = A[i].x1; x[++xsz] = A[i].x2; 137 y[++ysz] = A[i].y1; y[++ysz] = A[i].y2; 138 A[i].op = 0;A[i].id = tt; 139 ans[tt] = num; 140 } 141 } 142 sort(x+1, x+xsz+1); sort(y+1, y+ysz+1); 143 xsz = unique(x+1, x+1+xsz) - x - 1; 144 ysz = unique(y+1, y+1+ysz) - y - 1; 145 for(int i = 1; i <= n; i++){ 146 A[i].x1 = lower_bound(x+1, x+1+xsz, A[i].x1) - x; 147 A[i].x2 = lower_bound(x+1, x+1+xsz, A[i].x2) - x; 148 A[i].y1 = lower_bound(y+1, y+1+ysz, A[i].y1) - y; 149 A[i].y2 = lower_bound(y+1, y+1+ysz, A[i].y2) - y; 150 if(A[i].op){ 151 bit[0].add(A[i].x1, A[i].op); 152 bit[1].add(A[i].x2, A[i].op); 153 bit[2].add(A[i].y1, A[i].op); 154 bit[3].add(A[i].y2, A[i].op); 155 } 156 else { 157 num = ans[A[i].id]; 158 ans[A[i].id] -= num - bit[0].query(A[i].x2); 159 ans[A[i].id] -= bit[1].query(A[i].x1-1); 160 ans[A[i].id] -= num - bit[2].query(A[i].y2); 161 ans[A[i].id] -= bit[3].query(A[i].y1-1); 162 } 163 } 164 for(int i = 0; i < 4; i++) bit[i].Clear(); 165 cdq(1, n); 166 for(int i = 1; i <= tt; i++) 167 printf("%d\n", ans[i]); 168 return 0; 169 }