博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CodeChef - QRECT Rectangle Query CDQ分治
阅读量:7099 次
发布时间:2019-06-28

本文共 5684 字,大约阅读时间需要 18 分钟。

题解:现在需要维护的每次的询问矩形和前面插入的所有矩形有公共部分的个数。 我们试着直接去维护这个东西, 发现可能的情况太多,不好维护,所以我们维护每次询问的时候在当前矩阵个数下,有多少个矩阵是一定在外面的。对于一个矩阵来说, 我们只需要统计到目前位置, 多少个矩形的下底线 在询问矩形的上底线之上, 这样我们就减去了在询问矩形上方的不重合矩形。 然后我们对矩形的左右下也一样维护这个信息。对于这个操作我们可以用4个树状数组直接去维护这个信息。每个数状数组记录一下每条底线出现的位置。

维护完这个东西之后,我们发现如果一个矩形在询问矩形的左上方, 他会被减去2次,这样就多减了, 我们需要把左上角的矩形个数再加回去。 我们需要 对每个询问矩形来说, 维护出有多少个插入矩形的右下角的端点是在询问矩形的左上角的端点的左上角, 对于这个问题就变成了一个2维偏序问题,我们用cdq去维护这个信息。当然还有其他3个角落,我们也需要对那些角度做一样的操作。最后我们就可以得到答案了。

代码:

1 #include
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
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 }
View Code

 

转载于:https://www.cnblogs.com/MingSD/p/9772827.html

你可能感兴趣的文章
窗口大小改变绑定resize事件
查看>>
python数据结构之二叉树遍历的实现
查看>>
进出口流程 & 报关单据
查看>>
各主流浏览器内核介绍
查看>>
[LeetCode] Copy List with Random Pointe
查看>>
如何更深入地学习Linux?
查看>>
目标检測的图像特征提取之(一)HOG特征
查看>>
MySQL-EXPLAIN用法详解
查看>>
jdbctemplate中的query(sql,params,mapper)与queryForList(sql,params,class)区别
查看>>
C++ 虚函数表解析
查看>>
Responder一点也不神秘————iOS用户响应者链完全剖析
查看>>
Type mismatch: cannot convert from java.sql.PreparedStatement to com.mysql.jdbc.PreparedStatement
查看>>
thinkphp 重定向redirect
查看>>
Builder创建者模式
查看>>
安卓应用使用QQ登录的申请流程
查看>>
Android批量图片加载经典系列——采用二级缓存、异步加载网络图片
查看>>
redis 数据类型详解 以及 redis适用场景场合
查看>>
RAC安装重新运行root.sh
查看>>
Mac下面的SecureCRT(附破解方案) 更新到最新的7.3.2(转)
查看>>
Java多线程有哪几种实现方式? Java中的类如何保证线程安全? 请说明ThreadLocal的用法和适用场景...
查看>>