欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

『贪心』服务器需求

程序员文章站 2024-03-21 19:16:16
...

Problem\mathrm{Problem}

『贪心』服务器需求

Solution\mathrm{Solution}

我们设答案为xx,那么首先答案需要满足xaix\ge \forall a_i.

然后我们来考虑如何分配这xx台机器,我们发现:

  • 由于机器的使用天数是不连续的,每一台机器在每一天的贡献是独立的,因此只需要满足aix×m\sum a_i\le x\times m.

然后就得到结论:
max(maxi=1n(ai),i=1naim)\max(\max_{i=1}^{n}(a_i),\lceil \frac{\sum_{i=1}^{n}a_i}{m}\rceil)

我们维护最大值(用支持删除修改的set维护/线段树),区间和即可。

说一个使用setset的小坑点:

  • ss中删除所有元素大小为xx的数,用法是s.erase(x)s.\mathrm{erase}(x).
  • ss中删除一个元素大小为xx的数,用法是s.erase(s.find(x))s.\mathrm{erase}(s.\mathrm{find}(x)).

代码如下:

#include <set>
#include <cstdio>
#include <iostream>
#define int long long
 
using namespace std;
const int N = 5e5;
 
int n, m, q, sum(0);
int a[N];
multiset<int>s;
 
int read(void)
{
    int s = 0, w = 0; char c = getchar();
    while (c < '0' || c > '9') w |= c == '-', c = getchar();
    while (c >= '0' && c <= '9') s = s*10+c-48, c = getchar();
    return w ? -s : s;
}
 
int ans(void) {
    multiset<int>::iterator it = s.end();
    int ans = sum % m ? sum / m + 1 : sum / m;
    return max(*(--it),ans);
}
 
void change(void)
{
    int x = read(), v = read();
    s.erase(s.find(a[x]));
    s.insert(v);
    sum += -a[x] + (a[x] = v);
    printf("%lld\n", ans());
    return;
}