Educational Codeforces Round 61 (Rated for Div. 2) D. Stressful Training(貪心+二分)

Educational Codeforces Round 61 (Rated for Div. 2)

題意:有n臺電腦要使用,一共m分鐘,每臺電腦初始電量ai,每分鐘消耗bi,若你有一臺充電寶,那麼每分鐘至少衝多少電量,才能保證每分鐘所有電腦的電量都是>=0。

題解:首先根據題意可以很清楚的看出來應該可以二分,因爲若答案x可行,則答案x+1一定可行(顯然 :) ),但是如何check答案是一個難點,這裏我們可以用貪心算法,每次充電都給最早沒電的電腦衝,這顯然是正確的,那麼我們這裏有兩種算法進行實現:

Solve 1: O((n+m)lg^2(n)) 首先我們可以考慮有一個事件堆來維護,維護每一個事件沒電的那一天就可以了,實現比較簡單,但是複雜度偏高。

Solve 2:O((n+m)lg(n)) 其實對於m來說數據並不是很大,2e5,所以我們可以考慮進行桶排序,用lis[i]來保存第i天沒電的電腦的下標,然後一天一天的枚舉,然後維護即可~~~

#include<bits/stdc++.h>
using namespace std;
#define Sheryang main
const int maxn=1e6+7;
typedef long long ll;
const int mod=1e9+7;
void Smax(int &a,int b){if(a<b) a=b;}
void Smin(int &a,int b){if(a>b) a=b;}
///#define getchar()(p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
///char buf[(1 << 21) + 1], *p1 = buf, *p2 = buf;
#define IO cin.tie(0),ios::sync_with_stdio(false);
#define pi acos(-1)
#define PII pair<ll,ll>
ll read(){ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
#define read read()
/** keep hungry and keep calm! **/

ll a[maxn],b[maxn];
ll n,m;

struct node{
    ll a,b,c;
    bool operator <(const node &a)const{
        return a.c<c;
    }
};

bool judge(ll x){
    priority_queue<node>q;
    for(int i=1;i<=n;i++){
        q.push({a[i],b[i],a[i]/b[i]});
    }
    for(int i=1;i<=m;i++){
        node t=q.top();q.pop();
        if(t.c<i-1) return false;
        if(t.c>=m) return true;
        q.push({t.a+x,t.b,(t.a+x)/t.b});
    }
    return true;
}


int Sheryang()
{
    n=read,m=read;

    for(int i=1;i<=n;i++){
        a[i]=read;
    }
    for(int i=1;i<=n;i++){
        b[i]=read;
    }

    ll l=0,r=1e14,ans=-1;
    while(l<=r){
        ll mid=(l+r)/2;
        if(judge(mid)){
            ans=mid;
            r=mid-1;
        }else{
            l=mid+1;
        }
    }

    printf("%lld\n",ans);
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define Sheryang main
const int maxn=1e6+7;
typedef long long ll;
const int mod=1e9+7;
void Smax(int &a,int b){if(a<b) a=b;}
void Smin(int &a,int b){if(a>b) a=b;}
///#define getchar()(p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
///char buf[(1 << 21) + 1], *p1 = buf, *p2 = buf;
#define IO cin.tie(0),ios::sync_with_stdio(false);
#define pi acos(-1)
#define PII pair<ll,ll>
ll read(){ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
#define read read()
/** keep hungry and keep calm! **/

ll a[maxn],b[maxn],cur[maxn];
ll n,m;

vector<int>lis[maxn];
bool judge(ll x){
    for(int i=0;i<m;i++){
        lis[i].clear();
    }
    for(int i=0;i<n;i++){
        ll t=a[i]/b[i]+1;
        cur[i]=a[i]%b[i];
        if(t<m){
            lis[t].push_back(i);
        }
    }

    int now=1;
    for(int i=0;i<m;i++){
        while(now<m && lis[now].empty()){
            now++;
        }

        if(now==m) return true;
        if(now<=i) return false;

        int t=lis[now].back();
        if(cur[t]+x<b[t]){
            cur[t]+=x;
            continue;
        }
        lis[now].pop_back();
        ll nt=(cur[t]+x)/b[t];
        cur[t]+=x;cur[t]%=b[t];
        if(nt+now<m){
            lis[now+nt].push_back(t);
        }
    }
    return true;
}


int Sheryang()
{
    n=read,m=read;

    for(int i=0;i<n;i++){
        a[i]=read;
    }
    for(int i=0;i<n;i++){
        b[i]=read;
    }

    ll l=0,r=1e14,ans=-1;
    while(l<=r){
        ll mid=(l+r)/2;
        if(judge(mid)){
            ans=mid;
            r=mid-1;
        }else{
            l=mid+1;
        }
    }

    printf("%lld\n",ans);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章