「luogu3415」 祭坛

离散化,二分答案,扫描y轴,用树状数组统计个数即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=100010;
 4 int n,cntx[N],cnty[N],ans1,ans2;
 5 vector<int>px[N],py[N];
 6 struct P{
 7     int data,pos;
 8     bool operator<(const P& k)const{return data<k.data;};
 9 }x[N],y[N];
10 vector<P>s,t;
11 int totx,toty,a[N],b[N],bit[N];
12 inline int lowbit(int k){return k&(-k);}
13 inline void add(int pos,int x){while(pos<=toty) bit[pos]+=x,pos+=lowbit(pos);return;}
14 inline int que(int k){
15     int ans=0;
16     while(k) ans+=bit[k],k-=lowbit(k);
17     return ans;
18 }
19 int check(int k){
20     int spos,tpos,tots,tott,ans=0,ii=0,jj=0;
21     s.clear();t.clear();
22     memset(bit,0,sizeof(bit));
23     for(int i=1;i<=totx;i++){
24         spos=k-1,tpos=cntx[i]-k;
25         if(spos>=tpos) continue;
26         s.push_back((P){px[i][spos]+1,i});t.push_back((P){px[i][tpos],i});
27     }
28     sort(s.begin(),s.end());sort(t.begin(),t.end());
29     tots=s.size(),tott=t.size();
30     for(int i=1;i<=toty;i++){
31         while(ii<tots&&s[ii].data==i) add(s[ii++].pos,1);
32         while(jj<tott&&t[jj].data==i) add(t[jj++].pos,-1);
33         spos=k-1,tpos=cnty[i]-k;
34         if(spos>=tpos) continue;
35         ans+=que(py[i][tpos]-1)-que(py[i][spos]);
36     }
37     return ans;
38 }
39 int main(){
40     scanf("%d",&n);
41     for(int i=1;i<=n;i++) scanf("%d%d",&x[i].data,&y[i].data),x[i].pos=y[i].pos=i;
42     sort(x+1,x+n+1);sort(y+1,y+n+1);
43     x[0].data=y[0].data=-1;
44     for(int i=1;i<=n;i++){
45         if(x[i].data!=x[i-1].data) totx++;
46         if(y[i].data!=y[i-1].data) toty++;
47         a[x[i].pos]=totx,b[y[i].pos]=toty;
48     }
49     for(int i=1;i<=n;i++){
50         px[a[i]].push_back(b[i]);
51         py[b[i]].push_back(a[i]);
52     }
53     for(int i=1;i<=totx;i++){
54         cntx[i]=px[i].size(),cnty[i]=py[i].size();
55         if(cntx[i]>=2)sort(px[i].begin(),px[i].end());
56         if(cnty[i]>=2) sort(py[i].begin(),py[i].end());
57     }
58     int l=1,r=n/4;
59     while(l<=r){
60         int mid=(l+r)>>1;
61         int temp=check(mid);
62         if(temp) ans1=mid,ans2=temp,l=mid+1;
63         else r=mid-1;
64     }
65     printf("%d\n%d",ans1,ans2);
66     return 0;
67 }

 

posted @ 2018-03-11 20:24  Cupcake  阅读(151)  评论(0编辑  收藏  举报