Codeforces Round #123 (Div. 2) B - After Training

本文介绍了一种使用线段树数据结构解决特定分配问题的方法。问题涉及将一定数量的球分配给若干个篮子,确保每个篮子中球的数量尽可能均匀。通过维护区间内的最小值及其位置,并在更新过程中考虑最小值的特殊处理,实现了解决方案。

【题意】

有n个球和m个篮子,将球依次放进篮子里,优先放到球最少的篮子里,如果有多个这样的,则放到这样的篮子中,放到值最小的那个篮子中。问每个球分别放到了哪个篮子中。

【解题方法】

特别注意的一个细节,是一个实数,如果存到一个int里面,会造成错误的结果。这道题用线段树维护整个区间的最小值和最小值所在的位置。进行pushup的时候,如果左子树的最小值和右子树的最小值相等,就要将这个节点的最小值的位置就要进行比较维护。对于每一个球,输出当前最小值的位置,往最小值位置进行加1操作.

【AC 代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=100010;
struct node{
    int l,r;
    int minn,minp;
}Tree[maxn*4];

double MID;
void pushup(int rt)
{
    Tree[rt].minn=min(Tree[rt*2].minn,Tree[rt*2+1].minn);
    if(Tree[rt].minn==Tree[rt*2].minn) Tree[rt].minp=Tree[rt*2].minp;
    else Tree[rt].minp=Tree[rt*2+1].minp;
    if(Tree[rt*2+1].minn==Tree[rt].minn&&abs(Tree[rt].minp-MID)>abs(Tree[rt*2+1].minp-MID)){
        Tree[rt].minp=Tree[rt*2+1].minp;
    }
}
void Build(int l,int r,int rt)
{
    Tree[rt].l=l,Tree[rt].r=r;
    Tree[rt].minn=0;
    if(l==r){
        Tree[rt].minp=l;
        return ;
    }
    int mid=(l+r)/2;
    Build(l,mid,rt*2);
    Build(mid+1,r,rt*2+1);
    pushup(rt);
}
void update(int rt){
    if(Tree[rt].l==Tree[rt].r){
        printf("%d\n",Tree[rt].l);
        Tree[rt].minn++;
        return ;
    }
    int mid=(Tree[rt].l+Tree[rt].r)/2;
    if(Tree[rt].minp<=mid) update(rt*2);
    else update(rt*2+1);
    pushup(rt);
}
int main()
{
    int n,m;
    cin>>n>>m;
    MID=(m+1)/2.0;
    Build(1,m,1);
    for(int i=1; i<=n; i++) update(1);
    return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值