您的位置:首页 > Web前端

bzoj千题计划180:bzoj4411: [Usaco2016 Feb]Load balancing

2018-01-02 14:26 387 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=4411

用树状数组维护扫描线

一个树状数组维护扫描线之上的y<=i点,另一个维护扫描线之下y<=i的点

将点按x排好序,开始全部插入扫描线之下的树状数组

枚举x这一条线,线上的在第一个树状数组里加上,第二个树状数组里减去

最大值是一个单峰函数

可以用二分或三分

二分的话,哪边大往哪边移

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

#define N 100001

#define lowbit(x) x&-x

int m;

int c[2][N*10];

struct node
{
int x,y;
}e
;

void read(int &x)
{
x=0; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}

bool cmp(node p,node q)
{
return p.x<q.x;
}

void add(int t,int x,int w)
{
while(x<=m)
{
c[t][x]+=w;
x+=lowbit(x);
}
}

int query(int t,int x)
{
int sum=0;
while(x)
{
sum+=c[t][x];
x-=lowbit(x);
}
return sum;
}

int main()
{
int n;
read(n);
for(int i=1;i<=n;++i)
{
read(e[i].x);
read(e[i].y);
m=max(m,e[i].y);
}
for(int i=1;i<=n;++i) add(1,e[i].y,1);
sort(e+1,e+n+1,cmp);
int j;
int ans=n;
int l,r,mid,tmp;
int sum0,sum1,tot0,tot1;
for(int i=1;i<=n;i=j)
{
j=i;
while(j<=n && e[j].x==e[i].x)
{
add(1,e[j].y,-1);
add(0,e[j].y,1);
j++;
}
l=1; r=m;
tot0=query(0,m);
tot1=query(1,m);
tmp=1;
while(l<=r)
{
mid=l+r>>1;
sum0=query(0,mid);
sum1=query(1,mid);
if(max(sum0,sum1)>=max(tot0-sum0,tot1-sum1))
{
tmp=mid;
r=mid-1;
}
else l=mid+1;
}
sum0=query(0,tmp);
sum1=query(1,tmp);
ans=min(ans,max(max(sum0,sum1),max(tot0-sum0,tot1-sum1)));
}
cout<<ans;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: