【Foreign】Rectangle [KD-tree]
Rectangle
Time Limit: 50 Sec Memory Limit: 512 MBDescription
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 }