牛客假日团队赛58 - B Load Balancing(Platinum)

Load Balancing(Platinum)

https://ac.nowcoder.com/acm/contest/7158/B

B Load Balancing(Platinum)

前言

  • 赛时发现此题没有太多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周赛,团队赛,练习赛,挑战赛,各种模拟赛的部分题解

全部评论
Rubbish, a waste of my time. It's really disgusting. I suggest you quit this question
点赞 回复 分享
发布于 2020-11-10 10:38

相关推荐

不愿透露姓名的神秘牛友
11-27 10:52
点赞 评论 收藏
分享
手撕没做出来是不是一定挂
Chrispp3:不会,写出来也不一定过
点赞 评论 收藏
分享
牛客5655:其他公司的面试(事)吗
点赞 评论 收藏
分享
11-18 09:44
Java
小白也想要offer:简历别放洋屁,搞不还还放错了,当然你投外企除外,以上纯属个人观点
点赞 评论 收藏
分享
评论
3
1
分享
正在热议
# 25届秋招总结 #
442405次浏览 4511人参与
# 春招别灰心,我们一人来一句鼓励 #
41986次浏览 533人参与
# 阿里云管培生offer #
120251次浏览 2220人参与
# 地方国企笔面经互助 #
7962次浏览 18人参与
# 同bg的你秋招战况如何? #
76670次浏览 561人参与
# 虾皮求职进展汇总 #
115613次浏览 886人参与
# 北方华创开奖 #
107435次浏览 599人参与
# 实习,投递多份简历没人回复怎么办 #
2454658次浏览 34857人参与
# 实习必须要去大厂吗? #
55771次浏览 961人参与
# 提前批简历挂麻了怎么办 #
149901次浏览 1977人参与
# 投递实习岗位前的准备 #
1195935次浏览 18548人参与
# 你投递的公司有几家约面了? #
33206次浏览 188人参与
# 双非本科求职如何逆袭 #
662208次浏览 7394人参与
# 如果公司给你放一天假,你会怎么度过? #
4753次浏览 55人参与
# 机械人春招想让哪家公司来捞你? #
157628次浏览 2267人参与
# 如果你有一天可以担任公司的CEO,你会做哪三件事? #
11561次浏览 287人参与
# 发工资后,你做的第一件事是什么 #
12704次浏览 62人参与
# 工作中,努力重要还是选择重要? #
35804次浏览 384人参与
# 参加完秋招的机械人,还参加春招吗? #
20126次浏览 240人参与
# 我的上岸简历长这样 #
452016次浏览 8088人参与
# 实习想申请秋招offer,能不能argue薪资 #
39299次浏览 314人参与
# 非技术岗是怎么找实习的 #
155868次浏览 2120人参与
牛客网
牛客企业服务