Exemple #1
0
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;
}
Exemple #2
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;
}