ForeignRectangle KD-tree

Posted BearChild

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ForeignRectangle KD-tree相关的知识,希望对你有一定的参考价值。

Rectangle

Time Limit: 50 Sec  Memory Limit: 512 MB

Description

  

Input

  

Output

  

Sample Input

  0
  4
  2 0
  2 1
  1 1
  1 2
  4
  0 0 2 2
  1 1 2 2
  1 0 2 1
  0 0 1 1

Sample Output

  2 3
  2 2
  2 2
  1 1

HINT

  

Solution

  显然,如果我们求出了 last[i] 表示 在某个相同横/纵坐标下,前一个纵/横坐标的取值,那问题就转化为了三维偏序,且要求在线

  限制显然形如:L1 <= xi <= R1, L2 <= yi <= R2, last_i <= L3

  由于BearChild太菜了,它的 bitset 内存不够开。直接上个 KD-tree 卡卡常即可。

Code

  1 #include<iostream>
  2 #include<string>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cmath>
  8 using namespace std;
  9 typedef long long s64;
 10 
 11 const int ONE = 500005;
 12 const int Max = 500000;
 13 
 14 int get()
 15 {
 16         int res = 1, Q = 1; char c;
 17         while( (c = getchar()) < 48 || c > 57)
 18             if(c == \'-\') Q = -1;
 19         if(Q) res = c - 48;
 20         while( (c = getchar()) >= 48 && c <= 57)
 21             res = res * 10 + c - 48;
 22         return res * Q;
 23 }
 24 int T, n;
 25 
 26 struct node {int x, y;} fir[ONE];
 27 bool cmp_x(const node &a, const node &b) {return a.x < b.x || (a.x == b.x && a.y < b.y);}
 28 bool cmp_y(const node &a, const node &b) {return a.y < b.y || (a.y == b.y && a.x < b.x);}
 29 
 30 struct power {int c[3];};
 31 bool cmp_0(const power &a, const power &b) {return a.c[0] < b.c[0];}
 32 bool cmp_1(const power &a, const power &b) {return a.c[1] < b.c[1];}
 33 bool cmp_2(const power &a, const power &b) {return a.c[2] < b.c[2];}
 34 
 35 int Ans;
 36 struct ID
 37 {
 38         struct point {int lc, rc, size, l[3], r[3];} p[ONE];
 39         power a[ONE];
 40 
 41         int kd_num;
 42         void Update(point &x)
 43         {
 44             if(x.lc) x.size += p[x.lc].size;
 45             if(x.rc) x.size += p[x.rc].size;
 46             point y;
 47             if(x.lc) y = p[x.lc],
 48                 x.l[0] = min(x.l[0], y.l[0]), x.r[0] = max(x.r[0], y.r[0]),
 49                 x.l[1] = min(x.l[1], y.l[1]), x.r[1] = max(x.r[1], y.r[1]),
 50                 x.l[2] = min(x.l[2], y.l[2]), x.r[2] = max(x.r[2], y.r[2]);
 51             if(x.rc) y = p[x.rc],
 52                 x.l[0] = min(x.l[0], y.l[0]), x.r[0] = max(x.r[0], y.r[0]),
 53                 x.l[1] = min(x.l[1], y.l[1]), x.r[1] = max(x.r[1], y.r[1]),
 54                 x.l[2] = min(x.l[2], y.l[2]), x.r[2] = max(x.r[2], y.r[2]);
 55         }
 56 
 57         s64 calc(int l, int r, int id)
 58         {
 59             s64 x = 0, xx = 0;
 60             for(int i = l; i <= r; i++)
 61                 x += a[i].c[id], xx += (s64)a[i].c[id] * a[i].c[id];
 62             return (r - l + 1) * xx - x * x;
 63         }
 64 
 65         int root;
 66         int Build(int l, int r)
 67         {
 68             int mid = l + r >> 1;
 69             point &x = p[mid];
 70 
 71             s64 w0 = calc(l, r, 0), w1 = calc(l, r, 1), w2 = calc(l, r, 2);
 72             s64 w = max(w0, max(w1, w2));
 73 
 74             if(w == w0) nth_element(a + l, a + mid, a + r + 1, cmp_0);
 75             else
 76             if(w == w1) nth_element(a + l, a + mid, a + r + 1, cmp_1);
 77             else
 78             if(w == w2) nth_element(a + l, a + mid, a + r + 1, cmp_2);
 79 
 80             if(l < mid) x.lc = Build(l, mid - 1);
 81             if(mid < r) x.rc = Build(mid + 1, r);
 82 
 83             x.size = 1;
 84             x.l[0] = x.r[0] = a[mid].c[0];
 85             x.l[1] = x.r[1] = a[mid].c[1];
 86             x.l[2] = x.r[2] = a[mid].c[2];
 87             Update(x);
 88             return mid;
 89         }
 90 
 91         bool insect(const point &a, const point &b)
 92         {
 93             if(a.r[0] < b.l[0] || b.r[0] < a.l[0]) return 0;
 94             if(a.r[1] < b.l[1] || b.r[1] < a.l[1]) return 0;
 95             if(a.r[2] < b.l[2] || b.r[2] < a.l[2]) return 0;
 96             return 1;
 97         }
 98 
 99         bool contain(const point &a, const point &b) 
100         {
101             if(!(a.l[0] <= b.l[0] && b.r[0] <= a.r[0])) return 0;
102             if(!(a.l[1] <= b.l[1] && b.r[1] <= a.r[1])) return 0;
103             if(!(a.l[2] <= b.l[2] && b.r[2] <= a.r[2])) return 0;
104             return 1;
105         }
106 
107         bool contain(const point &a, const power &b)
108         {
109             if(!(a.l[0] <= b.c[0] && b.c[0] <= a.r[0])) return 0;
110             if(!(a.l[1] <= b.c[1] && b.c[1] <= a.r[1])) return 0;
111             if(!(a.l[2] <= b.c[2] && b.c[2] <= a.r[2])) return 0;
112             return 1;
113         }
114 
115         void Query(int i, const point &x)
116         {
117             point now = p[i];
118             if(!insect(x, now)) return;
119             if(contain(x, now)) {Ans += now.size; return;}
120             if(contain(x, a[i])) Ans++;
121             if(now.lc) Query(now.lc, x);
122             if(now.rc) Query(now.rc, x);
123         }
124 };
125 ID A, B;
126 
127 
128 void Make_1()//|
129 {
130         sort(fir + 1, fir + n + 1, cmp_y);
131         static int last[ONE];
132         for(int i = 0; i <= Max; i++) last[i] = -1;
133         for(int i = 1; i <= n; i++)
134         {
135             A.a[i].c[0] = fir[i].x;
136             A.a[i].c[1] = fir[i].y;
137             A.a[i].c[2] = last[fir[i].x];
138             last[fir[i].x] = fir[i].y;
139         }
140         A.root = A.Build(1, n);
141 }
142 
143 void Make_2()
144 {
145         sort(fir + 1, fir + n + 1, cmp_x);
146         static int last[ONE];
147         for(int i = 0; i <= Max; i++) last[i] = -1;
148         for(int i = 1; i <= n; i++)
149         {
150             B.a[i].c[0] = fir[i].x;
151             B.a[i].c[1] = fir[i].y;
152             B.a[i].c[2] = last[fir[i].y];
153             last[fir[i].y] = fir[i].x;
154         }
155         B.root = B.Build(1, n);
156 }
157 
158 int main()
159 {
160         T = get(), n = get();
161         for(int i = 1; i <= n; i++)
162             fir[i].x = get(), fir[i].y = get();
163         Make_1(), Make_2();
164         int Q = get(), lax = 0, lay = 0;
165         while(Q--)
166         {
167             int x_1 = get(), y_1 = get(), x_2 = get(), y_2 = get();
168             x_1 = x_1 + (lax + lay) * T, y_1 = y_1 + (lax + lay) * T;
169             x_2 = x_2 + (lax + lay) * T, y_2 = y_2 + (lax + lay) * T;
170             ID::point x;
171 
172             Ans = x.size = x.lc = x.rc = 0;
173             x.l[0] = x_1, x.r[0] = x_2, x.l[1] = y_1, x.r[1] = y_2;
174             x.l[2] = -1, x.r[2] = y_1 - 1;
175             A.Query(A.root, x), lax = Ans;
176             
177             Ans = x.size = x.lc = x.rc = 0;
178             x.l[0] = x_1, x.r[0] = x_2, x.l[1] = y_1, x.r[1] = y_2;
179             x.l[2] = -1, x.r[2] = x_1 - 1;
180             B.Query(B.root, x), lay = Ans;
181 
182             printf("%d %d\\n", lax, lay);
183         }
184 }
View Code

 

以上是关于ForeignRectangle KD-tree的主要内容,如果未能解决你的问题,请参考以下文章

Kd-Tree 插入顺序

KD-Tree

KD-tree讲解

KD-Tree总结

BZOJ-4520K远点对 KD-Tree + 堆

BZOJ-1941Hide and Seek KD-Tree