数星星

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<set>
#include<iostream>
#include<vector>
using namespace std;
const int MAXN=200005;
struct star
{int x,y;
 int left,right,up,down;
 int xsmall,xlarge,ysmall,ylarge;
 int TL,TR,BL,BR;
}; star a[MAXN];
int X[MAXN],Y[MAXN],xnum[MAXN],ynum[MAXN],xsum[MAXN],ysum[MAXN];;
int cnt[MAXN];
set<int>  list;
int n;
void prepare(int &size,int(&x)[MAXN])
{ size=1;
 sort(x+1,x+n+1);
 for(int i=2;i<=n;i++)
  {if(x[i]!=x[i-1])
   x[size]=x[i];
   size++;
  }
}
int rank(int k,int size,int(&a)[MAXN])
{int l=1,r=size;
 while(l<=r)
 {int mid=(l+r)/2;
  if(a[mid]==k)  return mid;
  if(a[mid]<k) l=mid+1;
  else r=mid-1;
 }
 return 0;
}
bool cmp2(star i,star j)
{return i.x<j.x||(i.x==j.x&&i.y<j.y);
}
bool cmp1(star i,star j)
{return i.y<j.y||(i.y==j.y&&i.x<j.x);
}
int lowbit(int x)
{ return (x&(-x));
}
void change(int x,int add,int size)
{ while(x<=size)
  {cnt[x]=cnt[x]+add;
   x=x+lowbit(x);
  }
}
int query(int x)
{int ans=0;
  while(x>0)
   {ans=ans+cnt[x];
   x=x-lowbit(x);
   }
   return ans;
}
int main()
{scanf("%d",&n);
 a[0].x=a[0].y=a[n+1].x=a[n+1].y=-1;
for(int i=1;i<=n;i++)
{scanf("%d%d",&a[i].x,a[i].y);
 X[i]=a[i].x;Y[i]=a[i].y;
}
int xsize,ysize;
prepare(xsize,X);
prepare(ysize,Y);
 
for(int i=1;i<=n;i++)
{  a[i].x=rank(a[i].x,xsize,X);
 a[i].y=rank(a[i].y,ysize,Y);
  xnum[a[i].x]++; ynum[a[i].y]++;
}
xsum[0]=ysum[0]=0;
 for(int i=1;i<=n;i++)
 { xsum[i]=xsum[i-1]+xnum[i];
    ysum[i]=ysum[i-1]+ynum[i];
 }
  for(int i=1;i<=n;i++)
  { a[i].xsmall=xsum[a[i].x-1];
    a[i].xlarge=n-a[i].xsmall-xnum[a[i].x];
     a[i].ysmall=ysum[a[i].y-1];
     a[i].ylarge=n-a[i].ysmall-ynum[a[i].y];
  }
  sort(a+1,a+n+1,cmp1);
  for(int i=1;i<=n;i++)
  {   if(a[i-1].y!=a[i].y)
         a[i].left=0;
        else a[i].left=a[i-1].left+1;
       a[i].right=ynum[a[i].y]-1-a[i].left;
       
  }
sort(a+1,a+n+1,cmp2);
     for(int i=1;i<=n;i++)
{if(a[i-1].x!=a[i].x)
   a[i].down=0;
   else a[i].down=a[i-1].down+1;
   a[i].up=xnum[a[i].x]-1-a[i].down;
}  
for(int i=1;i<=n;i++)
{a[i].BL=query(a[i].y-1)-a[i].down;
a[i].TL=a[i].xsmall-a[i].BL-a[i].left;
a[i].TR=a[i].ylarge-a[i].TL-a[i].up;
a[i].BR=a[i].ysmall-a[i].BL-a[i].down;
change(a[i].y,1,ysize);
}
int ans=0,pre=1;
list.clear();
for(int i=1;i<=n;i++)
if(a[i].x!=a[i+1].x)
 {int stan=n+1,olie=0;
  for(int j=pre;j<=i;j++)
  {stan=min(stan,a[j].TR+a[j].BL);
  olie=max(olie,a[j].TL+a[j].BR);
       }
      if(stan>=ans)
  {if(stan>ans)
    {ans=stan;
    list.clear();
    }
    list.insert(olie);
  }
  pre=i+1; 
 }
 cout<<ans<<endl;
 for(set<int>::iterator it=list.begin();it!=list.end();it++)
  printf("%d ",*it);
 
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值