Codeforces Round #613 (Div. 2): E. Delete a Segment

https://codeforces.com/contest/1285/problem/E

問題
区間を1つ選んで削除した後に残った重なる区間をunionする。
unionした後に残る区間の数を最大化せよ。

解法
区間をunionした後に残る区間の数は、区間を始点ソートして昇順ループまたは降順ループを回して求めることができる。
それらをいい感じにハイブリッドすると通った。

int n;
pair<int, int> seg[200000];
int last[200000];
int cnt[200000];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int t;
	cin >> t;
	rep(_, t) {
		cin >> n;
		rep(i, n) {
			int a, b;
			cin >> a >> b;
			seg[i] = make_pair(a, b);
		}
		sort(seg, seg + n);

		int inf = 1000000001;
		int ans = 0, c = 0;
		int las = -inf;
		rep(i,n) {
			if (las < seg[i].first) {
				c++;
			}
			las = max(las, seg[i].second);
			last[i] = las;
			cnt[i] = c;
		}
	
		vector<int> vec;
		for (int i = n - 1; i >= 1; i--) {
			int num = cnt[i - 1];
			num += lower_bound(all(vec), last[i - 1], greater<int>()) - vec.begin();
			ans = max(ans, num);

			while (!vec.empty() && vec.back() <= seg[i].second) {
				vec.pop_back();
			}
			vec.push_back(seg[i].first);
		}
		ans = max<int>(ans, vec.size());

		cout << ans << endl;
	}
	return 0;
}