洛谷 P1204 [USACO1.2] 挤牛奶Milking Cows

题意:给定n个区间,左端点和右端点表示工作开始时间和结束时间。求最长一直有人在工作的时间和无人工作的时间。

思路:想到了并查集,还有差分树状数组,最后选择差分数组。左端点加,右端点减,然后一次遍历即可。

总结:习惯性的在右端点+1的位置减少了1,但是不适用于这个题目的逻辑。 因为在右端点+1的位置修改数值的话,结束的时间会变晚。

void solve(){
    int n;
    cin >> n;

    int maxn = int(1e6);
    vector<int> b(maxn + 10);

    int start = maxn;
    int last = 0;
    while (n -- ){
        int l, r;
        cin >> l >> r;
        start = min(start, l);
        last = max(last, r);
        b[l] ++;
        b[r] --;
    }

    for (int i = 1; i <= last; ++i){
        b[i] += b[i - 1];
    }

    array<int, 2> ans{};

    int i = start;
    while (i < last){
        int j = i;
        bool state = bool(b[i]);
        while (j <= last && bool(b[j]) == state){
            j ++;
        }
        ans[state] = max(ans[state], j - i);
        i = j;
    }

    cout << ans[1] << ' ' << ans[0] << '\n';
}
posted @ 2024-04-20 13:14  _Yxc  阅读(7)  评论(0编辑  收藏  举报