bzoj5102

$贪心$

$按左端点排序。$

$当我们钦定了最右的左端点,那么自然希望右端点尽量靠右$

$考虑之前的区间,那么我们相当于选之前的区间中第k大的右端点$

$堆维护一下就可以了,每次把新的元素放进堆,如果能更新就弹出旧的,否则弹出自己$

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 1e6 + 5;
int n, k, ans;
struct data {
    int l, r, id;
    bool friend operator < (const data &a, const data &b) {
        return a.l < b.l;
    }
} a[N];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;
int main() {
//  freopen("1.in", "r", stdin);
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; ++i) {
        scanf("%d%d", &a[i].l, &a[i].r);
        a[i].id = i;
    }
    sort(a + 1, a + n + 1);
    for(int i = 1; i < k; ++i) {
        q.push(make_pair(a[i].r, a[i].id));
    }
    for(int i = k; i <= n; ++i) {
        q.push(make_pair(a[i].r, a[i].id));
        ans = max(ans, q.top().first - a[i].l);
        q.pop();
    }
    printf("%d
", ans);
    while(!q.empty()) {
        q.pop();
    }
    for(int i = 1; i < k; ++i) {
        q.push(make_pair(a[i].r, a[i].id));
    }
    for(int i = k; i <= n; ++i) {
        q.push(make_pair(a[i].r, a[i].id));
        if(ans == q.top().first - a[i].l) {
            vector<int> v;
            while(!q.empty()) {
                v.push_back(q.top().second);
                q.pop();
            }
            sort(v.begin(), v.end());
            for(int i = 0; i < v.size(); ++i) {
                printf("%d ", v[i]);
            }
            return 0;
        }
        q.pop();
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/19992147orz/p/8461875.html