# 【Foreign】Rectangle [KD-tree]

## Rectangle

Time Limit: 50 Sec  Memory Limit: 512 MB

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

2 3
2 2
2 2
1 1

## 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

posted @ 2018-01-05 19:57  BearChild  阅读(...)  评论(...编辑  收藏