网络优化

题目大意

有一个区间,有条网络,第条网络的服务区间为,但是它只能提供个人的服务。
问:如何分配才能使得同一时间上线的人数最多?

分析

那么就考虑对于每一个点它是否能够被覆盖到,贪心即可。
那么贪心过程就可以是从左到右枚举区间上的每一个点,然后在符合条件的服务器中扣除一个人的服务。
那么如何来维护符合条件的服务器呢?

  • 先将左右的服务器按左端点从小到大排序
  • 将所有的的服务器加入到优先队列中
  • 把所有或者不能再提供服务的服务器弹出
    • 如果此时优先队列不为空,那么这个人可以上线,有的贡献,将这个服务器的服务人数减一
    • 如果此时优先队列为空,那么这个人无法上线了,没有贡献

时间复杂度大概是

Code

#include <queue>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 1e5 + 10;

inline int __read()
{
    int x(0);
    char o(getchar());
    while (o < '0' || o > '9') o = getchar();
    for (; o >= '0' && o <='9'; o = getchar()) 
        x = (x << 1) + (x << 3) + (o ^ 48);
    return x;
}

struct Node
{
    int l, r, v;
    bool operator < (const Node &T) const{
        if (l == T.l && r == T.r) return v < T.v;
        else if (l == T.l) return r < T.r;
        return l < T.l;
    }
}server[maxn];

struct Tree
{
    int rest, r;
    Tree () {}
    Tree (int rest, int r) : rest(rest), r(r) {}
    bool operator < (const Tree &T) const {
        if (r == T.r) return rest > T.rest;
        return r > T.r;
    }
};

int n, m;
int main()
{
    while (~scanf ("%d %d", &n, &m)) {
        for (int i = 1; i <= m; ++i)
            server[i].l = __read(), server[i].r = __read(), server[i].v = __read();
        sort (server + 1, server + m + 1);
        priority_queue <Tree> Q;
        int cnt(1), ans(0);
        for (int i = 1; i <= n; ++i) {
            while (server[cnt].l == i) {
                Q.push(Tree(server[cnt].v, server[cnt].r));
                ++cnt;
            }
            while (!Q.empty() && (Q.top().r < i || !Q.top().rest))
                Q.pop();
            if (Q.empty()) continue;
            Tree T = Q.top();
            T.rest--;
            Q.pop();
            Q.push(T);
            ++ans;
        }
        printf ("%d\n", ans);
    }
}