由于这几天刚好有事,这题目拖了好几天,今天总算静下心来搞定了。题目并不难,只是有点繁琐,而且要注意细节。
简要思路:
先把数据离散化,同时记录每一个X左右边有多少,X有多少,Y同理;
然后按先X再Y从小到大排序,再来扫描,用线段树记录区间里点的个数。
然后推出四个象限的点的个数,麻烦的事来了,坐标上的点怎么去掉,开了cntx,cnty记录每个X,Y坐标询问次数,然后就很简单了。
最后把第二个人的结果排序再去重就OK了;
ACcode:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using std::sort;
const int nsize=222222;
struct Point
{
int x,y;
} pot[nsize];
int n,k,nx,ny,maxs;
int maxy[nsize],num[nsize<<2];
int lft[nsize],rgt[nsize];
int up[nsize],down[nsize];
int curx[nsize],cury[nsize];
int *px[nsize],*py[nsize];
int cntx[nsize],cnty[nsize];
int Max(int a1,int a2)
{
return a1>a2?a1:a2;
}
int Min(int a1,int a2)
{
return a1<a2?a1:a2;
}
bool cmp1(int *a1,int *a2)
{
return *a1<*a2;
}
bool cmp2(Point a1,Point a2)
{
if (a1.x==a2.x) return a1.y<a2.y;
return a1.x<a2.x;
}
void leave()
{
int i,tx,ty;
sort(px,px+n,cmp1);
sort(py,py+n,cmp1);
nx=ny=1;
tx=*px[0],ty=*py[0];
*px[0]=*py[0]=1;
lft[0]=lft[1]=0;
down[0]=down[1]=0;
for (i=1; i<n; i++)
{
if (*px[i]!=tx)
{
tx=*px[i];
curx[nx]=i-lft[nx];
rgt[nx]=n-i;
lft[++nx]=i;
}
*px[i]=nx;
if (*py[i]!=ty)
{
ty=*py[i];
cury[ny]=i-down[ny];
up[ny]=n-i;
down[++ny]=i;
}
*py[i]=ny;
}
rgt[nx]=up[ny]=0;
curx[nx]=n-lft[nx];
cury[ny]=n-down[ny];
}
int query(int rt,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return num[rt];
int m=(l+r)>>1,ans=0;
if (L<=m) ans+=query(rt<<1,l,m,L,R);
if (R>m) ans+=query(rt<<1|1,m+1,r,L,R);
return ans;
}
void PushUp(int rt)
{
num[rt]=num[rt<<1]+num[rt<<1|1];
}
void update(int rt,int l,int r,int p)
{
if (l==r)
{
num[rt]++;
return ;
}
int m=(l+r)>>1;
if (p<=m) update(rt<<1,l,m,p);
else update(rt<<1|1,m+1,r,p);
PushUp(rt);
}
void solve()
{
int i,tx,ty;
int lu,ld,ru,rd;
int mins=nsize,may=-1;
maxs=0,k=0;
sort(pot,pot+n,cmp2);
memset(num,0,sizeof(num));
memset(cntx,0,sizeof(cntx));
memset(cnty,0,sizeof(cnty));
for (i=0; i<n; i++)
{
tx=pot[i].x;
ty=pot[i].y;
lu=query(1,1,ny,ty+1,ny);
ld=lft[tx]-lu-cnty[ty];
rd=down[ty]-ld-cntx[tx];
ru=up[ty]-lu-(curx[tx]-cntx[tx]-1);
// ru=n-curx[tx]-cury[ty]+1-ld-rd-lu;
mins=Min(mins,ld+ru);
may=Max(may,lu+rd);
update(1,1,ny,ty);
cntx[tx]++;
cnty[ty]++;
if (i==(n-1)||(tx!=pot[i+1].x))
{
if (maxs<mins)
{
maxs=mins;
maxy[0]=may;
k=1;
}
else if (maxs==mins)
maxy[k++]=may;
mins=nsize,may=-1;
}
}
printf("Stan: %d; Ollie:",maxs);
sort(maxy,maxy+k);
for (ty=i=1; i<k; i++)
if (maxy[i]!=maxy[i-1]) maxy[ty++]=maxy[i];
for (i=0; i<ty; i++) printf(" %d",maxy[i]);
puts(";");
}
int main()
{
int i;
while (scanf("%d",&n)&&n)
{
for (i=0; i<n; i++)
{
scanf("%d %d",&pot[i].x,&pot[i].y);
px[i]=&pot[i].x,py[i]=&pot[i].y;
}
leave();
solve();
}
return 0;
}