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; }