您的位置:首页 > Web前端

bzoj4411 [Usaco2016 Feb] Load balancing

2016-03-03 21:12 330 查看

Description

给出N个平面上的点。保证每一个点的坐标都是正奇数。
你要在平面上画两条线,一条是x=a,一条是y=b,且a和b都是偶数。
直线将平面划成4个部分,要求包含点数最多的那个部分点数最少。

Input

第一行一个数N。
接下来N行每行描述一个点
N<=100000
1<=x,y<=1000000

Output

输出一个数表示最少的点数。

枚举直线x=a的位置,将两侧的点的y坐标插入线段树中,在线段树查询在x=a确定时y=b的最优位置。

#include<cstdio>
#include<algorithm>
int n,ans=2147483647;
inline int read(){
int x=0,c=getchar();
while(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x;
}
struct pos{
int x,y;
}ps[100005];
bool operator<(pos a,pos b){return a.x<b.x;}
int t1[262144],t2[262144];
int tran[1000005];
void ins(int*t,int x){for(x+=131071;x;x>>=1)t[x]++;}
void del(int*t,int x){for(x+=131071;x;x>>=1)t[x]--;}
void cal(int x1,int x2){
int w=1,v1=t1[2],v2=t2[2],u1,u2,mx;
while(1){
u1=x1-v1;
u2=x2-v2;
mx=v1;
if(v2>mx)mx=v2;
if(u1>mx)mx=u1;
if(u2>mx)mx=u2;
if(ans>mx)ans=mx;
if(w>=65536)break;
if(v1==mx||v2==mx){
w+=w;
v1-=t1[(w<<1)+1];
v2-=t2[(w<<1)+1];
}else{
w+=w+1;
v1+=t1[w<<1];
v2+=t2[w<<1];
}
}
}
int main(){
n=read();
for(int i=0;i<n;i++){
ps[i].x=read();
tran[ps[i].y=read()]=1;
}
std::sort(ps,ps+n);
for(int i=1,w=1;i<=1000000;i++)if(tran[i])tran[i]=w++;
for(int i=0;i<n;i++)ps[i].y=tran[ps[i].y];
for(int i=0;i<n;i++)ins(t2,ps[i].y);
cal(0,n);
ps
.x=-1;
for(int i=0;i<n;i++){
del(t2,ps[i].y);
ins(t1,ps[i].y);
if(ps[i].x!=ps[i+1].x)cal(i+1,n-i-1);
}
printf("%d",ans);
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: