51nod3110 小明爱区间

3110 小明爱区间

小明最近非常喜欢区间,于是他想出来这样一个问题:
给定平行于x轴的 n 条线段。每个线段的左右端点坐标都是整数。有些线段可以退化成点。线段之间可以相互交叉,嵌套,甚至重合。

这样所有 x 轴上的整数点最少被 0 条线段覆盖,最多同时被 n 条线段覆盖。

你的任务是:求出 x 轴上,分别被 k 条线段覆盖的,坐标为整数的点的数量。(1\leq k\leq n)。

注意:被线段的左右端点覆盖也算是覆盖。

输出共 n 个数,第 1 个数表示被 1 条线段覆盖的整点数量,第 2 个数表示被2线段覆盖的整点数量......

输入

输入的第一行包含一个整数n(1≤n≤2*10^5)—线段的数量。
接下来的n行。
第i行包含一对整数li,ri(0≤li≤ri≤10^18),表示第i段的端点。

输出

输出包括一行n个数字,第i个数字表示被i条线段覆盖的点的数目。

数据范围

对于10%的数据,1<= n <= 8
对于50%的数据,1 <= n<= 1024
对于100%的数据,1 <= n <= 200000
0≤li≤ri≤10^18。

输入样例

3
0 3
1 3
3 8

输出样例

6 2 1

样例解释

解析:

我们知道,每一个区间的贡献是1,那么我便可以在区间的左端点加1,右端点减1,这样可以累加过去,便可以实现这个区间的每一个数字加1,对每一个区间都这样操作,我们不用遍历每一个数字,对区间的端点从小到大排序,对于排序后的端点,我们可以O(1)计算出这个区间的有多少个数字有着相同的贡献,贡献的数值直接累加端点值即可,具体看代码,时间复杂度O(nlogn)。

放代码:

#include <bits/stdc++.h>
#define N 200010
#define ll long long
using namespace std;
int n,ans[N];
struct node
{
    ll pos;
    int id;//id==0?l:r
    bool operator < (const node &t)
    {
        return pos<t.pos;
    }
}p[N<<1];
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>p[i*2-1].pos>>p[i*2].pos;
        p[i*2].pos++,p[i*2].id=1;
    }
    sort(p+1,p+1+2*n);
    p[0]=p[1];
    for(int i=1,cnt=0;i<=2*n;i++)
    {
        ans[cnt]+=p[i].pos-p[i-1].pos;
        if(!p[i].id)cnt++;
        else cnt--;
    }
    for(int i=1;i<=n;i++)cout<<ans[i]<<" \n"[i==n];
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值