zhengruioi 470 区间

区间

链接

题意:给定n个区间[li,ri]。你可以选出任意一些区间,设选出的区间个数是s,[l,r]是这些区间的交,求min(s,r-l+1)的最大值。 N≤3×105

分析:首先按照左端点排序,然后依次加入每条线段。加入后判断min(s, r-l+1)哪个大。如果s大,那么说明答案受限制与区间交,所以可以考虑去掉一些线段,去掉右端点最小的(堆维护);如果s小,那么继续加入线段即可。

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;

inline int read() {
    int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}

const int N = 600005;
struct Edge{ 
    int l, r; 
    bool operator < (const Edge &A) const { return l < A.l; }
} A[N];
priority_queue<int, vector<int>, greater<int> > q;

int main() { 
    int n = read();
    for (int i = 1; i <= n; ++i) A[i].l = read(), A[i].r = read();
    sort(A + 1, A + n + 1);
    int ans = 1, cnt = 1;
    q.push(A[1].r);
    for (int i = 2; i <= n; ++i) {
        cnt ++;
        q.push(A[i].r); ;
        ans = max(ans, min(cnt, q.top() - A[i].l + 1));
        while (!q.empty() && q.top() - A[i].l + 1 < cnt) {
            cnt --;
            q.pop();
            ans = max(ans, min(cnt, q.top() - A[i].l + 1));
        }
        ans = max(ans, min(cnt, q.top() - A[i].l + 1));
    }
    cout << ans;
    return 0;
}
原文地址:https://www.cnblogs.com/mjtcn/p/10333211.html