Covered Points Count CodeForces - 1000C
原题链接
考察:思维
思路:
比较容易想到离散化,然后让L点权值为1,R点权值为-1.这里需要分类讨论:
(1) 当前枚举点有左端点,此时再计算上个点到此点的距离,\(ans[当前权值和] = v[now] - v[last]\)
(2) 当前枚举到有右端点,此时\(ans[当前权值和] = v[now] - v[last]+1\)
注意到左端点公式与右端点公式只差了一个1,考虑把右端点右移一个1.最后枚举所有点即可,这样就不用讨论既有L,又有R的情况.
Code
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 200010;
vector<LL> v;
struct Segment{
LL l,r;
bool operator<(const Segment s)const{
return this->l<s.l;
}
}seg[N];
int n,L[N<<1];
LL ans[N];
int get(LL x)
{
return lower_bound(v.begin(),v.end(),x)-v.begin();
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&seg[i].l,&seg[i].r);
v.push_back(seg[i].l);
v.push_back(seg[i].r+1);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
for(int i=1;i<=n;i++)
{
int a = get(seg[i].l);
L[a]++;
int b = get(seg[i].r+1);
L[b]--;
}
LL sta = 0,cnt = 0;
for(int i=0;i<v.size();i++)
{
LL x = v[i];
ans[cnt]+=x-sta;
sta = v[i];
cnt+=L[i];
}
for(int i=1;i<=n;i++)
printf("%lld ",ans[i]);
return 0;
}