牛客假日团队赛58 - B Load Balancing(Platinum)
Load Balancing(Platinum)
https://ac.nowcoder.com/acm/contest/7158/B
前言
- 赛时发现此题没有太多AC,就先放着了,事后发现这的确是一道好题
分析
- 画个图了解一下题意
 设M为这四个区域中点数的最大数量,求一个划分方案是的M最小
- 正经东西:
 那么M=max(a,b,c,d),如何求到每一个格子中点的数量呢?首先考虑简单一点的——如何维护一个范围内点的数量。这样肯定能用离散+树状数组维护。假设我们将坐标 y 离散,这个树状数组(1号)维护的是纵坐标小于等于 y 的点的数量,那么当前我们知道的即是 c + d ,a + b 。 但是不够啊,我得知道单个的QwQ,不然没法儿算。于是就来了一个方法——枚举横坐标x,将横坐标小于等于 x 的点加入到另一个树状数组(2号)中去 这样的话,就可以直接求得 c , a 的值,至于 b , d怎么求就不用说了。
- 大致过程:离散纵坐标,把点加入到一号树状数组,枚举横坐标 x ,把横坐标小于等于 x 的点加入到二号树状数组,在纵坐标上面进行三分,求得最小的M,
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,cnt,ans;
int p[N],k[N],b[N];
//0,1
struct nkl
{
    int l,r;
}s[N];
inline bool god(nkl xx,nkl yy)
{
    return xx.l<yy.l;
}
inline int lowbit(int x)
{
    return x&(-x);
}
inline void add(int x,int id)
{
    while(x<=cnt)
    {
        if(id==1) ++k[x];
        else ++p[x];
        x+=lowbit(x);
    }
}
inline int find(int x,int id)
{
    int res=0;
    while(x)
    {
        if(id==1) res+=k[x];
        else res+=p[x];
        x-=lowbit(x);
    }
    return res;
}
inline int sum(int x,int tot)
{
    int xx=find(x,0);//左下 
    int yy=tot-xx;//左上 
    int ano=find(x,1)-xx;//右下
    return max(xx,max(yy,max(ano,n-xx-yy-ano)));    
}
inline int get(int tot)
{
    int l=1,r=cnt,res=1e9;
    while(l+1<r)
    {
        int lm=l+(r-l)/3,rm=r-(r-l)/3;
        int xx=sum(lm,tot),yy=sum(rm,tot);
        res=min(res,min(xx,yy));
        if(xx>yy) l=lm+1;
        else r=rm-1;
    }
    return res;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d%d",&s[i].l,&s[i].r);
        b[i]=s[i].r;
    }sort(b+1,b+n+1);
    cnt=unique(b+1,b+n+1)-b-1;
    for (int i=1;i<=n;i++)
        s[i].r=lower_bound(b+1,b+cnt+1,s[i].r)-b;
    sort(s+1,s+n+1,god);
    for (int i=1;i<=n;i++) add(s[i].r,1);
    int ans=1e9;
    for (int i=1,now;i<=n;i=now+1)
    {
        now=i;
        while(now<=n&&s[now].l==s[i].l) now++;
        now--;
        for (int j=i;j<=now;j++) add(s[j].r,0);
        ans=min(ans,get(now));
    }
    printf("%d\n",ans);
    return 0;
}比赛题解 文章被收录于专栏
 牛客IOI周赛,团队赛,练习赛,挑战赛,各种模拟赛的部分题解
 投递百度等公司10个岗位
投递百度等公司10个岗位