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 }
相關文章
相關標籤/搜索