区间
题意:给定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; }