zoukankan      html  css  js  c++  java
  • Codeforces 1132D

    题目链接:https://codeforces.com/contest/1132/problem/D

    题意:

    有 $n$ 个学生,他们的电脑有初始电量 $a[1 sim n]$,他们的电脑每分钟会耗电 $b[1 sim n]$,现在有一场比赛持续 $k$ 分钟。

    要你买一个充电器,使得每个学生的电脑在比赛期间的任何时候的电量都不会低于 $0$(可以等于 $0$),你要求出这个充电器每分钟充电量最少是多少。

    题解:

    看到这种题目,应当条件反射想到二分。

    假设我们现在知道充电器每分钟的充电量是 $x$,那么如何确保比赛能够进行呢?

    一台电脑的初始电量为 $a$,耗电量为 $b$,如果不充电的话,显然在 $lfloor frac{a}{b} floor+1$ 这一分钟是最后一分钟了,再下一分钟就负电量了。

    所以,我们找到这个 $lfloor frac{a}{b} floor$ 最小的电脑,这是最快用完电的那台电脑,我们应当优先给他充电。

    所以在当前这一分钟,我们选择给它冲一分钟的电,很重要的一个思想,我们此时不维护每个电脑的当前电量,而是在初始电量上直接加上 $x$,因为这两个操作是等价的。

    然后在下一分钟,我们继续找此时最快会没电的电脑,继续给它充一分钟的电。

    这样一来,对于一个 $x$ 进行check的时间复杂度是 $O((k+n)log n)$,而二分 $x$ 的范围是 $[0,k cdot max_{i=1}^{n}(b_i)]$,记 $L = k cdot max_{i=1}^{n}(b_i)$。所以总时间复杂度是 $O(log L cdot (k+n) cdot log n)$。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+10;
    
    int n,k;
    ll a[maxn],b[maxn];
    
    struct Qnode{
        ll a,b;
        ll r;
        bool operator<(const Qnode& oth)const {
            return r>oth.r;
        }
    };
    
    inline bool check(ll x)
    {
        priority_queue<Qnode> Q;
        for(int i=1;i<=n;i++) Q.push((Qnode){a[i],b[i],a[i]/b[i]});
        for(int t=1;t<=k;t++)
        {
            Qnode q=Q.top(); Q.pop();
            if(q.a/q.b+1ll<t) return 0;
            if(q.a/q.b+1ll>=k) return 1;
            Q.push((Qnode){q.a+x,q.b,(q.a+x)/q.b});
        }
        return 1;
    }
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
    
        cin>>n>>k;
        for(int i=1;i<=n;i++) cin>>a[i];
        ll bmax=0;
        for(int i=1;i<=n;i++) cin>>b[i], bmax=max(b[i],bmax);
    
        ll l=0, r=(k-1)*bmax+1;
        while(l<r)
        {
            ll mid=(l+r)>>1;
            if(check(mid)) r=mid;
            else l=mid+1;
        }
        if(l>=(k-1)*bmax+1) cout<<-1<<'
    ';
        else cout<<l<<'
    ';
    }

    注意,这个题还有一个点,就是优先队列里的元素,我们按照 $a/b$ 来排序,需要开一个变量 $r = a / b$ 来减少六十四位除法的次数,来加快比较速度,否则会TLE。

  • 相关阅读:
    表达式计算
    atof和atoi
    十六进制与十进制之间的相互转换
    十六进制转八进制
    B. Blown Garland
    B. Arpa’s obvious problem and Mehrdad’s terrible solution
    ios::sync_with_stdio(false);
    1091 线段的重叠
    CODE[VS] 2614 安全区域
    CODE[VS] 2221 搬雕像 ——2011年台湾高级中学咨询学科能力竞赛
  • 原文地址:https://www.cnblogs.com/dilthey/p/10513790.html
Copyright © 2011-2022 走看看