int main() { #ifndef ONLINE_JUDGE // GenBig(); // freopen("big.txt", "r", stdin); // freopen("input.txt", "r", stdin); GenInt(); freopen("int.txt", "r", stdin); #endif #ifndef __linux__ SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); #endif int m; scanf("%d", &m); int size = m + 8; long double* xcd = (long double*)_mm_malloc(sizeof(long double)*size, 32); long double* ycd = (long double*)_mm_malloc(sizeof(long double)*size, 32); long double mx = 1e-5; for (int i = 0; i < m; ++i) { scanf("%Lf%Lf", &xcd[i], &ycd[i]); mx = Max(mx, abs(xcd[i])); mx = Max(mx, abs(ycd[i])); } TIntVector indices(m); for (int i = 0; i < m; ++i) { indices[i] = i; } for (int i = 0; i < m; ++i) { swap(indices[i], indices[i + (rand() % (m - i))]); } TDoubles xc(m); TDoubles yc(m); for (int i = 0; i < m; ++i) { xc[i] = xcd[indices[i]] / mx; yc[i] = ycd[indices[i]] / mx; } KDTree* kdTree = new KDTree(0, xc, yc, indices); // CircleTree* cTree = new CircleTree(0, xc, yc, indices); int n; scanf("%d", &n); vector<int> result; result.reserve(m); vector<int> result2; result2.reserve(m); for (int i = 0; i < n; ++i) { long double xd, yd; scanf("%Lf%Lf", &xd, &yd); double x = xd/mx; double y = yd/mx; TVector x2; x2.v = _mm_set1_pd(x); TVector y2; y2.v = _mm_set1_pd(y); result.clear(); double minDist = 1e100; TVector minMax; minMax.v = _mm_set1_pd(minDist); double minMin = minDist; kdTree->Solve(x, y, x2, y2, &minDist, &minMax, &minMin, &result); // cTree->Solve(x, y, x2, y2, &minDist, &minMax, &minMin, &result); if (result.size() < 5) { result2.clear(); long double mind = 1e15; long double mindMin = mind; long double mindMax = mind; for (auto realindex : result) { long double dist = Sqr(xd - xcd[realindex]) + Sqr(yd - ycd[realindex]); static const long double LDEPS = 1e-10; if (dist < mindMin) { mind = dist; mindMin = dist - LDEPS; mindMax = dist + LDEPS; result2.clear(); } if (dist <= mindMax) { result2.push_back(realindex); } } } else { result2 = result; } sort(result2.begin(), result2.end()); result2.erase(unique(result2.begin(), result2.end()), result2.end()); Output(result2); } return 0; }
int main() { #ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); #endif #ifndef __linux__ SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); #endif int m; scanf("%d", &m); int size = m + 8; long double* xcd = (long double*)_mm_malloc(sizeof(long double)*size, 32); long double* ycd = (long double*)_mm_malloc(sizeof(long double)*size, 32); __m128d* xyd = (__m128d*)_mm_malloc(sizeof(__m128d)*size, 32); long double mx = 1e-12; for (int i = 0; i < m; ++i) { scanf("%Lf%Lf", &xcd[i], &ycd[i]); mx = Max(mx, abs(xcd[i])); mx = Max(mx, abs(ycd[i])); xyd[i] = _mm_set_pd(xcd[i], ycd[i]); } mx = Max(mx, (long double)1e-8); TIntVector indices(m); for (int i = 0; i < m; ++i) { indices[i] = i; } for (int i = 0; i < m; ++i) { swap(indices[i], indices[i + (rand() % (m - i))]); } TFloats xc(m); TFloats yc(m); for (int i = 0; i < m; ++i) { xc[i] = xcd[indices[i]] / mx; yc[i] = ycd[indices[i]] / mx; } KDTree* kdTree = new KDTree(0, xc, yc, indices); int n; scanf("%d", &n); vector<int> result; result.reserve(m); vector<int> result2; result2.reserve(m); for (int i = 0; i < n; ++i) { long double xd, yd; scanf("%Lf%Lf", &xd, &yd); float x = xd / mx; float y = yd / mx; __m128 x4 = _mm_set1_ps(x); __m128 y4 = _mm_set1_ps(y); __m128d xy = _mm_set_pd(xd, yd); result.clear(); float minDist = 1e20f; __m128 minMax = _mm_set1_ps(minDist); float minMin = minDist; kdTree->Solve(x, y, x4, y4, &minDist, &minMax, &minMin, &result); sort(result.begin(), result.end()); result.erase(unique(result.begin(), result.end()), result.end()); if (result.size() < 1000000) { result2.clear(); long double mind = 1e100; long double mindMin = mind; long double mindMax = mind; for (auto realindex : result) { __m128d xyd2 = _mm_sub_pd(xyd[realindex], xy); xyd2 = _mm_mul_pd(xyd2, xyd2); long double dist = GET_ITEM2(xyd2, 0) + GET_ITEM2(xyd2, 1); static const long double LDEPS = 1e-10; if (dist < mindMin) { mind = dist; mindMin = dist - LDEPS; mindMax = dist + LDEPS; result2.clear(); } if (dist <= mindMax) { result2.push_back(realindex); } } } else { result2 = result; } Output(result2); } return 0; }