1285E
扫描线
先跑一个扫描线 统计不删除的答案 然后考虑对于每个线段计算删除的答案
思考一下什么情况下删除线段答案增加
当扫描线扫到了一个右端点 并且set里只有一条线段
这时set里的线段贡献+1 这里比较好思考
还要注意如果当前线段只有一条 那么答案-1
一条线段右端点也可能造成贡献 但是不用特别计算 因为全局答案包括了 可以想象成本身属于原先左右相交的线段的一部分 这样删除后不会对答案造成贡献
感觉大力想一想问题不大
#include <bits/stdc++.h> using namespace std; const int maxn = 4e5 + 5; int n; int cnt[maxn]; int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); vector<pair<int, int> > v; for(int i = 1; i <= n; ++i) { int l, r; scanf("%d%d", &l, &r); v.emplace_back(l, -i); v.emplace_back(r, i); cnt[i] = 0; } sort(v.begin(), v.end()); v.emplace_back(0, 0); set<int> s; int ans = 0; for(int i = 0; i < (int)v.size() - 1; ++i) { if(v[i].second < 0) { s.insert(-v[i].second); } else { s.erase(v[i].second); } if(s.empty()) { ++ans; } if(s.size() == 1) { if(v[i].second > 0 && v[i + 1].second < 0 && v[i + 1].first > v[i].first) { ++cnt[*s.begin()]; } if(v[i].second < 0 && v[i + 1].second > 0) { --cnt[*s.begin()]; } } } int t = -1; for(int i = 1; i <= n; ++i) { t = max(t, cnt[i]); } printf("%d\n", ans + t); } return 0; }