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;
}
posted @ 2021-06-28 14:31  acmloser  阅读(28)  评论(0编辑  收藏  举报