Codeforces Round #501 (Div. 3) 1015A Points in Segments

题目:http://codeforces.com/contest/1015/problem/A

题目大意:n个线段 [l, r], 然后1~m个点,输出哪些点不属于任何线段。

当然是个水题,时间复杂度O(n*m), 如果  n,m <= 10^7呢?

可以用前缀和O(n+m)解答:

给出  l,r  暴力想法直接 vis[l]~vis[r] 标记 1,但是有更好的想法。

将 vis[l]++,  vis[r+1]-- ,求前缀和的时候,虽然中间的没有标记1,但是前缀和往后延申就达到标记效果了。将vis[r+1]--, 传到r+1的时候就(-1) + 1 = 0,  也就是没有出现过了。

例如 :  点1  2  3 4 5

给出线段 【2 4】, 【4,5】;可以看出答案为   1

点              0    1    2     3      4      5       6

[2,4]           0     0    1     0     0      -1      0

[4,5]           0     0    1     0     1       0      -1

前缀和       0     0    1     1     2       2       1(只有点1为0)

AC代码(原题解):

#include <bits/stdc++.h>

using namespace std;

int main() {
#ifdef _DEBUG
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	
	int n, m;
	cin >> n >> m;
	vector<int> cnt(m + 2);
	for (int i = 0; i < n; ++i) {
		int l, r;
		cin >> l >> r;
		++cnt[l];
		--cnt[r + 1];
	}
	for (int i = 1; i <= m; ++i)
		cnt[i] += cnt[i - 1];
	vector<int> ans;
	for (int i = 1; i <= m; ++i) {
		if (cnt[i] == 0)
			ans.push_back(i);
	}
	
	cout << ans.size() << endl;
	for (auto it : ans) cout << it << " ";
	cout << endl;
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40932661/article/details/81394377