bzoj1577 [Usaco2009 Feb]庙会捷运Fair Shuttle

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1577

【题解】

我们把每坨奶牛按s排个序。

对于每坨奶牛,如果车上有空位置就塞。

否则,看下车上是否有奶牛的e值比他大,就把这个奶牛扔下去(当做没上过车),把新的奶牛拉上来(因为更大的区间显然不优)。

每次操作前遍历set看是否有奶牛到站了,下车即可。

最后记得加上s.size。时间复杂度O(nclogn)

# include <set>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

int n, m, c;
struct pa {
    int s, e, num;
    pa() {}
    pa(int s, int e, int num) : s(s), e(e), num(num) {}
    friend bool operator <(pa a, pa b) {
        return a.e < b.e;
    }
}p[M];

inline bool cmp(pa a, pa b) {
    return a.s < b.s || (a.s == b.s && a.e < b.e);
}

multiset<pa> s;
multiset<pa>::iterator it, tem;

int main() {
    cin >> m >> n >> c;
    for (int i=1; i<=m; ++i) scanf("%d%d%d", &p[i].s, &p[i].e, &p[i].num);
    sort(p+1, p+m+1, cmp);
    int cnt = 0;
    for (int i=1; i<=m; ++i) {
        for (it = s.begin(); it != s.end();) {
            if((*it).e <= p[i].s) {
                cnt ++;
                tem = it;
                ++it;
                s.erase(tem);
            } else ++it;
        }
        if(s.size() < c) {
            while(p[i].num && s.size() < c) {
                s.insert(p[i]);
                --p[i].num;
            }
        }
        if(p[i].num) {
            it = --s.end();
            while(p[i].num && (*it).e > p[i].e) {
                s.erase(it);
                s.insert(p[i]);
                --p[i].num;
                it = --s.end();
            }
        }
//        for (it = s.begin(); it != s.end(); ++it) cout << (*it).s << ' ' << (*it).e << ' ' << (*it).num << endl;
//        cout << i << ' ' << s.size() << endl;
    }
    cout << cnt + s.size();
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/galaxies/p/bzoj1577.html