1 /*
2 题意:给你n个点,先选一条过至少一个点的垂线,然后在垂线上选一个点,过该点做水平线,
3 将图分成四部分,记为ul,ur,dl,dr,问选一条直线使得对于最坏情况选的水平线下,使得dl+ur最大的值;
4 同时输出在dl+ur最大的情况下ul+dr的可能值;
5
6 思路:先离散,因为题目没有说明数据范围,
7 然后依次枚举每一条垂直线,再从下到上枚举每一个点,利用树状数组记录;
8 最后输出解;
9
10 */
11
12 #include<cstdio>
13 #include<cstring>
14 #include<cstdlib>
15 #include<set>
16 #include<algorithm>
17 #include<cmath>
18 #include<iostream>
19 #include<vector>
20 using namespace std;
21 const int N=200000+10;
22 int n;
23 int n1,n2;
24 int c1[N],c2[N];
25 vector<int> X,Y,g[N];
26 inline int lowbit(int x){
27 return x&-x;
28 }
29 inline void add(int c[],int x,int v){
30 for (int i=x;i<N;i+=lowbit(i)){
31 c[i]+=v;
32 }
33 }
34 inline int sum(int c[],int x){
35 int ret=0;
36 for (int i=x;i>0;i-=lowbit(i)){
37 ret+=c[i];
38 }
39 return ret;
40 }
41 int x[N],y[N];
42 void read(){
43 memset(c1,0,sizeof(c1));
44 memset(c2,0,sizeof(c2));
45 X.clear();Y.clear();
46
47 for (int i=0;i<n;i++){
48 scanf("%d%d",x+i,y+i);
49 X.push_back(x[i]);
50 Y.push_back(y[i]);
51 }
52 sort(X.begin(),X.end());
53 n1=unique(X.begin(),X.end())-X.begin();
54 sort(Y.begin(),Y.end());
55 n2=unique(Y.begin(),Y.end())-Y.begin();
56
57 for (int i=0;i<=n;i++) g[i].clear();
58 for (int i=0;i<n;i++){
59 int tmp=(lower_bound(X.begin(),X.begin()+n1,x[i])-X.begin())+1;
60 int tmp2=(lower_bound(Y.begin(),Y.begin()+n2,y[i])-Y.begin())+1;
61 g[tmp].push_back(tmp2);
62 add(c1,tmp2,1);
63 }
64 }
65 void work(){
66 int ret=-1;
67 vector<int> ans;
68 ans.clear();
69 for (int i=0;i<=n;i++){
70 int sz=g[i].size();
71 if (sz!=0){
72 vector<int> ans1;
73 ans1.clear();
74 int rt1=-1,a1,a2,a3,a4;//四个象限ul,ur,dl,dr;
75 sort(g[i].begin(),g[i].end());
76 for (int j=0;j<sz;j++){
77 int t1=sum(c1,g[i][j]-1);
78 a3=sum(c2,g[i][j]-1);
79 a4=t1-a3-j;
80 int t2=sum(c1,N-1)-sum(c1,g[i][j]);
81 a1=sum(c2,N-1)-sum(c2,g[i][j]);
82 a2=t2-a1-(sz-j-1);
83 if (a2+a3<rt1 || rt1==-1) {
84 rt1=a2+a3;
85 ans1.clear();
86 ans1.push_back(a1+a4);
87 }else if(a2+a3==rt1){
88 ans1.push_back(a1+a4);
89 }
90 }
91 for (int j=0;j<sz;j++){
92 add(c2,g[i][j],1);
93 }
94 if (rt1>ret || ret==-1){
95 ret=rt1;
96 ans.clear();
97 for (int j=0;j<ans1.size();j++){
98 ans.push_back(ans1[j]);
99 }
100 }else if (rt1==ret){
101 for(int j=0;j<ans1.size();j++){
102 ans.push_back(ans1[j]);
103 }
104 }
105 }
106 }
107 sort(ans.begin(),ans.end());
108 int n2=unique(ans.begin(),ans.end())-ans.begin();
109 printf("Stan: %d; Ollie:",ret);
110 for (int i=0;i<n2;i++){
111 printf(" %d",ans[i]);
112 }printf(";\n");
113 }
114 int main(){
115 while (~scanf("%d",&n),n){
116 read();
117 work();
118 }
119 return 0;
120 }