[Usaco2010]Chocolate Eating

5 5
10
40
13
22
7

24
1
1
3
4
5

分析:二分枚举最小值,尽可能让巧克力最晚吃。

#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#define range(i,a,b) for(int i=a;i<=b;++i)
#define LL long long
#define rerange(i,a,b) for(int i=a;i>=b;--i)
#define fill(arr,tmp) memset(arr,tmp,sizeof(arr))
using namespace std;
int n,m,val[50005],ans[50005];
LL sum;
void init() {
    cin>>n>>m;
    range(i,1,n)cin>>val[i],sum+=val[i];
}
bool judge(LL a){
    LL sum=0,cnt=0;
    range(i,1,m){
        while(sum<a&&cnt<=n)sum+=(LL)val[cnt++];
        if(sum<a)return false;
        sum>>=1;
    }
    return true;
}
void solve(){
    LL lef=0,ri=sum,tmpans=0;
    while(lef<=ri){
        LL mid=(lef+ri)/2;
        if(judge(mid))tmpans=max(tmpans,mid),lef=mid+1;
        else ri=mid-1;
    }
    cout<<tmpans<<endl;
    LL tsum=0,cnt=0;
    range(i,1,m){
        while(tsum<tmpans&&cnt<=n)tsum+=(LL)val[cnt],ans[cnt]=i,++cnt;
        tsum>>=1;
    }
    range(i,1,n)cout<<(ans[i]?ans[i]:m)<<endl;
}
int main() {
    init();
    solve();
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/Rhythm-/p/9333626.html