USACO 2016 February Contest Load Balancing (bzoj4411)
给出N个平面上的点。保证每一个点的坐标都是正奇数。
你要在平面上画两条线,一条是x=a,一条是y=b,且a和b都是偶数。
直线将平面划成4个部分,要求包含点数最多的那个部分点数最少。
看了https://blog.csdn.net/commonc/article/details/52457655的博客后。
枚举+二分。
1 #include <stdio.h> 2 #include <algorithm> 3 #include <cstring> 4 #include <cmath> 5 #include <queue> 6 #include <vector> 7 using namespace std; 8 const int maxn=1e5+10; 9 int n,ans=2147483647; 10 int c[2][maxn*10]; 11 struct hh 12 { 13 int x,y; 14 }a[maxn]; 15 template <class T> void read(T&x) 16 { 17 x=0;char c=getchar();int f=0; 18 while(c<'0'||c>'9'){f|=(c=='-');c=getchar();} 19 while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar(); 20 x=f?-x:x; 21 } 22 bool cmp(const hh&a,const hh&b){return a.x<b.x;} 23 void change(int k,int x,int v) 24 { 25 for(;x<=n;x+=x&-x) 26 c[k][x]+=v; 27 28 } 29 int check(int k,int x) 30 { 31 int ret=0; 32 for(;x;x-=x&-x) 33 ret+=c[k][x]; 34 return ret; 35 } 36 int main() 37 { 38 int m;read(m); 39 for(int i=1;i<=m;i++) 40 { 41 read(a[i].x);read(a[i].y); 42 n=max(n,a[i].y); 43 } 44 for(int i=1;i<=m;i++)change(1,a[i].y,1); 45 sort(a+1,a+m+1,cmp); 46 int l,r,mid,j; 47 for(int i=1;i<=m;i=j) 48 { 49 j=i; 50 while(a[j].x==a[i].x&&j<=m) 51 { 52 change(1,a[j].y,-1); 53 change(0,a[j].y,1); 54 j++; 55 } 56 l=1,r=n; 57 int t1,t2; 58 int tt1=check(0,n),tt2=check(1,n); 59 while(l<r) 60 { 61 mid=l+r>>1; 62 t1=check(0,mid),t2=check(1,mid); 63 if(max(t1,t2)>=max(tt1-t1,tt2-t2))r=mid; 64 else l=mid+1; 65 } 66 t1=check(0,l),t2=check(1,l); 67 ans=min(ans,max(max(t1,t2),max(tt1-t1,tt2-t2))); 68 } 69 printf("%d",ans); 70 return 0; 71 }