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;
}
posted on 2012-04-10 17:25  Staginner  阅读(442)  评论(0编辑  收藏  举报