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 }

 

posted @ 2018-07-10 23:04  新手-周  阅读(159)  评论(0编辑  收藏  举报