AtCoder Beginner Contest 221 D - Online games

题目描述

在这里插入图片描述

Sample Input

3
1 2
2 3
3 1

Sample Output

Copy
2 2 0

题目大意

先输入数字N,代表有N个注册者,然后接下来有N行,每一行有两个数字 A i , B i A_i,B_i Ai,Bi A i A_i Ai代表第 i i i个使用者的第一次登录的时间, B i B_i Bi代表第 i i i个使用者连续登录的天数。输出有N个数字,第k个数字代表第k天有多少个使用者登录。
其实也就是给定n条线段, [ l i , r i ] [l_i,r_i] [li,ri]。对于每个k值,输出每个k值被多少条线段覆盖。

实现思路

假如说我们现在平面上有n条线段,然后我们有一个标记竖线record从左到右扫描

  • 每次遇到线段的左端点,record+1
  • 每次遇到线段的右端点,record-1
  • record的值就是当前k位置的结果了

但是有一种特殊的情况,假如说以最左的点为左端点的线段有多条,那么我们上面的做法就会导致结果错误,大家可以在纸上模拟一下。所以我们需要特判

  • 当多个相同的左端点是最左边的点时,我们要更新一下答案
  • 不是最左边的点,就不需要更新答案。

完整代码

#include 
typedef long long ll;
using namespace std;
int main()
{ll n;cin >> n;vector<pair<ll, ll>> vt;ll a, b;for (int i = 0; i < n; i++){cin >> a >> b;vt.push_back(make_pair(a, 1));vt.push_back(make_pair(a + b, -1));}int now = 0;int p = 0;int ans[n + 1];memset(ans, 0, sizeof(ans));sort(vt.begin(), vt.end());int len = vt.size();for (int i = 0; i < len; i++){if (i > 0 && vt[i].first != vt[i - 1].first)ans[now] += vt[i].first - p;p = vt[i].first;now += vt[i].second;}for (int i = 1; i <= n; i++){cout << ans[i] << " ";}cout << endl;
}

题目链接


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部