POJ 2464 Brownie Points II

POJ_2464

    这个题目就是把POJ_2352数星星从一个象限拓展到了四个象限,把以每个点为中心四个象限内的点数都计算出来之后,只要枚举Stan所划的那条竖线的位置,并根据实际情况更新结果即可。

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#define INF 0x3f3f3f3f

#define MAXD 200010

int N, sum[4 * MAXD], tx[MAXD], ty[MAXD], X, Y, tr[MAXD], tl[MAXD], dl[MAXD], dr[MAXD], xn[MAXD], yn[MAXD], ans[MAXD], P;

struct Point

{

    int x, y, r;

}point[MAXD];

int cmpint(const void *_p, const void *_q)

{

    int *p = (int *)_p, *q = (int *)_q;

    return *p < *q ? -1 : 1;

}

int cmpxdyu(const void *_p, const void *_q)

{

    Point *p = (Point *)_p, *q = (Point *)_q;

    if(p->x == q->x)

        return p->y < q->y ? -1 : 1;

    return p->x < q->x ? 1 : -1;

}

int cmpxuyu(const void *_p, const void *_q)

{

    Point *p = (Point *)_p, *q = (Point *)_q;

    if(p->x == q->x)

        return p->y < q->y ? -1 : 1;

    return p->x < q->x ? -1 : 1;

}

int BSx(int x)

{

    int mid, min = 0, max = X;

    for(;;)

    {

        mid = (min + max) >> 1;

        if(mid == min)

            break;

        if(tx[mid] <= x)

            min = mid;

        else

            max = mid;

    }

    return mid;

}

int BSy(int y)

{

    int mid, min = 0, max = Y;

    for(;;)

    {

        mid = (min + max ) >> 1;

        if(mid == min)

            break;

        if(ty[mid] <= y)

            min = mid;

        else

            max = mid;

    }

    return mid;

}

void build(int cur, int x, int y)

{

    int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;

    sum[cur] = 0;

    if(x == y)

        return ;

    build(ls, x, mid);

    build(rs, mid + 1, y);

}

void update(int cur)

{

    sum[cur] = sum[cur << 1] + sum[(cur << 1) | 1];

}

void refresh(int cur, int x, int y, int k)

{

    int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;

    if(x == y)

    {

        ++ sum[cur];

        return ;

    }

    if(k <= mid)

        refresh(ls, x, mid, k);

    else

        refresh(rs, mid + 1, y, k);

    update(cur);

}

int getsum(int cur, int x, int y, int s, int t)

{

    int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;

    if(x >= s && y <= t)

        return sum[cur];

    if(mid >= t)

        return getsum(ls, x, mid, s, t);

    else if(mid + 1 <= s)

        return getsum(rs, mid + 1, y, s, t);

    else

        return getsum(ls, x, mid, s, t) + getsum(rs, mid + 1, y, s, t);

}

void prepare()

{

    int i, j, k, x, y;

    qsort(point, N, sizeof(point[0]), cmpxdyu);

    memset(xn, 0, sizeof(xn[0]) * X);

    memset(yn, 0, sizeof(yn[0]) * Y);

    build(1, 0, Y - 1);

    for(i = 0; i < N; i ++)

    {

        x = BSx(point[i].x), y = BSy(point[i].y);

        dr[point[i].r] = getsum(1, 0, Y - 1, 0, y) - xn[x] - yn[y];

        refresh(1, 0, Y - 1, y);

        ++ xn[x], ++ yn[y];

    }

    memset(xn, 0, sizeof(xn[0]) * X);

    memset(yn, 0, sizeof(yn[0]) * Y);

    build(1, 0, Y - 1);

    for(i = N - 1; i >= 0; i --)

    {

        x = BSx(point[i].x), y = BSy(point[i].y);

        tl[point[i].r] = getsum(1, 0, Y - 1, y, Y - 1) - xn[x] - yn[y];

        refresh(1, 0, Y - 1, y);

        ++ xn[x], ++ yn[y];

    }

    qsort(point, N, sizeof(point[0]), cmpxuyu);

    memset(xn, 0, sizeof(xn[0]) * X);

    memset(yn, 0, sizeof(yn[0]) * Y);

    build(1, 0, Y - 1);

    for(i = 0; i < N; i ++)

    {

        x = BSx(point[i].x), y = BSy(point[i].y);

        dl[point[i].r] = getsum(1, 0, Y - 1, 0, y) - xn[x] - yn[y];

        refresh(1, 0, Y - 1, y);

        ++ xn[x], ++ yn[y];

    }

    memset(xn, 0, sizeof(xn[0]) * X);

    memset(yn, 0, sizeof(yn[0]) * Y);

    build(1, 0, Y - 1);

    for(i = N - 1; i >= 0; i --)

    {

        x = BSx(point[i].x), y = BSy(point[i].y);

        tr[point[i].r] = getsum(1, 0, Y - 1, y, Y - 1) - xn[x] - yn[y];

        refresh(1, 0, Y - 1, y);

        ++ xn[x], ++ yn[y];

    }

}

void init()

{

    int i, j, k, x, y;

    for(i = 0; i < N; i ++)

    {

        scanf("%d%d", &x, &y);

        point[i].r = i, point[i].x = x, point[i].y = y;

        tx[i] = x, ty[i] = y;

    }

    qsort(tx, N, sizeof(tx[0]), cmpint);

    qsort(ty, N, sizeof(ty[0]), cmpint);

    X = Y = 0;

    for(i = 0; i < N; i ++)

    {

        if(i == 0 || tx[i] != tx[i - 1])

            tx[X ++] = tx[i];

        if(i == 0 || ty[i] != ty[i - 1])

            ty[Y ++] = ty[i];

    }

    prepare();

}

void solve()

{

    int i, j, k, score = -1, min, max;

    for(i = 0; i < N; i ++)

    {

        min = INF, max = -1;

        for(;;)

        {

            j = tr[point[i].r] + dl[point[i].r], k = tl[point[i].r] + dr[point[i].r];

            if(j < min)

                min = j;

            if(k > max)

                max = k;

            if(i == N - 1 || point[i + 1].x != point[i].x)

                break;

            ++ i;

        }

        if(min > score)

        {

            score = min;

            P = 0;

            ans[P ++] = max;

        }

        else if(min == score)

            ans[P ++] = max;

    }

    qsort(ans, P, sizeof(ans[0]), cmpint);

    printf("Stan: %d; Ollie:", score);

    for(i = 0; i < P; i ++)

        if(i == 0 || ans[i] != ans[i - 1])

            printf(" %d", ans[i]);

    printf(";\n");

}

int main()

{

    for(;;)

    {

        scanf("%d", &N);

        if(!N)

            break;

        init();

        solve();

    }

    return 0;

}

你可能感兴趣的:(poi)