CF1000C Covered Points Count

Covered Points Count

题目链接

题目描述

You are given n n n segments on a coordinate line; each endpoint of every segment has integer coordinates. Some segments can degenerate to points. Segments can intersect with each other, be nested in each other or even coincide.

Your task is the following: for every k ∈ [ 1.. n ] k \in [1..n] k[1..n] , calculate the number of points with integer coordinates such that the number of segments that cover these points equals k k k . A segment with endpoints l i l_i li and r i r_i ri covers point x x x if and only if l i ≤ x ≤ r i l_i \le x \le r_i lixri .

输入格式

The first line of the input contains one integer n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \le n \le 2 \cdot 10^5 1n2105 ) — the number of segments.

The next n n n lines contain segments. The i i i -th line contains a pair of integers l i , r i l_i, r_i li,ri ( 0 ≤ l i ≤ r i ≤ 1 0 18 0 \le l_i \le r_i \le 10^{18} 0liri1018 ) — the endpoints of the i i i -th segment.

输出格式

Print n n n space separated integers c n t 1 , c n t 2 , … , c n t n cnt_1, cnt_2, \dots, cnt_n cnt1,cnt2,,cntn , where c n t i cnt_i cnti is equal to the number of points such that the number of segments that cover these points equals to i i i .

题面翻译

题目大意:

给你n个区间,求被这些区间覆盖层数为 k ( k < = n ) k(k<=n) k(k<=n)的点的个数

输入格式:

第一行一个整数, n n n n < = 2 ∗ 1 0 5 n<=2*10^5 n<=2105

以下 n n n行,每行有两个整数,即这个区间的左右端点 l , r ( 0 < = l < = r < = 1 0 18 ) l,r(0<=l<=r<=10^{18}) l,r(0<=l<=r<=1018)

输出格式:

n n n个整数,即每个被覆盖层数对应的点的个数

样例 #1

样例输入 #1

3
0 3
1 3
3 8

样例输出 #1

6 2 1

样例 #2

样例输入 #2

3
1 3
2 4
5 7

样例输出 #2

5 2 0

提示

The picture describing the first example:

Points with coordinates [ 0 , 4 , 5 , 6 , 7 , 8 ] [0, 4, 5, 6, 7, 8] [0,4,5,6,7,8] are covered by one segment, points [ 1 , 2 ] [1, 2] [1,2] are covered by two segments and point [ 3 ] [3] [3] is covered by three segments.

The picture describing the second example:

Points [ 1 , 4 , 5 , 6 , 7 ] [1, 4, 5, 6, 7] [1,4,5,6,7] are covered by one segment, points [ 2 , 3 ] [2, 3] [2,3] are covered by two segments and there are no points covered by three segments.

思路

看到这个题第一时间想到用前缀和扫一遍,但看一眼数据范围可以发现 l 0 < = l < = r < = 1 0 18 l0<=l<=r<=10^{18} l0<=l<=r<=1018很明显会爆,再看一眼会发现 n < = 2 ∗ 1 0 5 n<=2*10^5 n<=2105可以将所有区间的左右端点存起来再排序,之后扫一遍就可以了
那么我们就用一个 n o w now now 记录当前段被覆盖了几次,然后枚举排序后前缀和改变的节点,把每次改变之前的一段中的节点数加入覆盖数为 n o w now now 的答案,最后修改 n o w now now 的值即可。还要注意一点:每一个线段的左端点和右端点的节点类型是不一样的,遇到左端点要 n o w + + now++ now++,右端点则要 n o w − − now-- now

代码

/*************************************************
Note:CF1000C
*************************************************/
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <iomanip>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#define ll long long
#define ull unsigned long long
using namespace std;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
inline int read()
{
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            w = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
        s = s * 10 + ch - '0', ch = getchar();
    return s * w;
}
int n;
ll ans[N];
struct node
{
    ll p;
    int k;
};
bool cmp(node x, node y)
{
    return x.p == y.p ? x.k < y.k : x.p < y.p;
}
vector<node> q;
int main()
{
    ll l, r;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> l >> r;
        q.push_back((node){l, 1});
        q.push_back((node){r + 1, -1});
    }
    sort(q.begin(), q.end(), cmp);
    ll last = 0, now = 0;
    for (int i = 0; i < q.size(); i++)
    {
        ll nex = q[i].p;
        ans[now] += q[i].p - last;
        now += q[i].k, last = nex;
    }
    for (int i = 1; i <= n; i++)
        cout << ans[i] << " ";
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

꧁Q༒ོγ꧂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值