[CodeForces - 1000C] Covered Points Count【差分】

题意

给n段区间的左右端点,问出现k次的点有几个,其中k = [1, n].

思路

就是一个差分嘛~

但是因为区间范围过大,所以不可能暴力整个范围,所以我们如何来统计次数呢?

对于区间端点,左端1,右断-1,按照端点升序排序。

定义now为当前点的个数,初始化当然是1,遍历[1, cnt),次数为now的点的个数自然就是info[i].pos - info[i - 1].pos

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

typedef long long ll;

inline ll read()
{
    ll x = 0, f = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') f = -f; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    return x * f;
}

const int maxN = 200005;

struct node{
    ll pos, d;
    node() {}
    node(ll a, ll b): pos(a), d(b) {}
    friend bool operator < (node n1, node n2) { return n1.pos < n2.pos; }
}info[maxN << 1];

ll n;
ll ans[maxN];

int main()
{
    int cnt = 0;
    n = read();
    for(int i = 0; i < n; ++ i )
    {
        ll l = read(), r = read();
        info[cnt ++ ] = node(l, 1);
        info[cnt ++ ] = node(r + 1, -1);
    }
    sort(info, info + cnt);
    ll now = 1;
    for(int i = 1; i < cnt; ++ i )
    {
        ans[now] += (info[i].pos - info[i - 1].pos);
        now += info[i].d;
    }
    for(int i = 1; i <=  n; ++ i )
        printf("%lld%c", ans[i], " \n"[i == n]);
    return 0;
}

说起来,其实不是没有接触过差分。很早那会,有人给我讲他比赛热身赛的一道题,就是差分。比这道题简单点,因为数据范围没有那么大。直接暴力就好了。

当时让我自己想,还想了很久,未果。后来他讲了,回去记了笔记,但是没有告诉我叫差分,(可能他自己也不知道(手动滑稽)后边直接忘了qaq

后来接触差分就是树状数组区间更新

但始终没有很懂吧(实话讲不是很会用树状数组,虽然短,但还是喜欢线段树

补补补补补!

冲!

发布了242 篇原创文章 · 获赞 68 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/104578329