C. Covered Points Count (线段问题---差分、排序)

51 篇文章 3 订阅
12 篇文章 0 订阅

题目

两种解法:

1.用差分思想,l—r所有点加1用map[l]+1,mdp[r+1]-1表示,前缀和即是当前点所对应覆盖线段数。

Code:

#include<iostream>
#include<stack>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int Max = 1e6 + 5;
ll a[Max], b[Max];
pair<ll, ll> lst[Max];
map<ll, ll> ma, mp;

int main()
{	
	int n;cin >> n;
	for (int i = 1;i <= n;i++)
	{
		ll l, r;cin >> l >> r;
		ma[l]++;
		ma[r + 1]--;
	}
	ll last = ma.begin()->first;
	ll sum = ma.begin()->second;
	for (auto i = ma.begin();i != ma.end();i++)
	{
		if (i == ma.begin())continue;
		mp[sum] += i->first - last;
		last = i->first;
		sum += i->second;
	}
	for (int i = 1;i <= n;i++)cout << mp[i] << " ";
}

排序模拟算贡献:

先将所有的左右端点排序,相同坐标起点放终点前面。每次遇到一个左端当前覆盖线段数+1,遇到右端当前覆盖线段数-1,每遇到一个改变的地方处理一批点,就是说之前那一批点覆盖的线段数量都相同。还有些细节处理,如果前面的改变处是左端则前面的左端那个点还没计算过点数+1,是右端表示前面的那个点已经计算过点数-1,同理现在的这个改变处是左端点数-1,右端点数+1,细节见代码。

Code:

#include<iostream>
#include<stack>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int Max = 1e6 + 5;
ll a[Max], b[Max];
pair<ll, ll> lst[Max];
map<ll, ll> ma;
int main()
{	
	int n;cin >> n;
	for (int i = 1;i <= n;i++)
	{
		ll l, r;cin >> l >> r;
		lst[i * 2 - 1] = make_pair(l, ll(0));
		lst[i * 2] = make_pair(r, ll(1));
	}
	sort(lst + 1, lst + 1 + 2 * n);
	ll sum = 1;
	for (int i = 2;i <= n*2;i++)
	{
		ll q = 0;
		if (lst[i].second == 0)
		{
			q = lst[i].first - lst[i - 1].first - 1;
			if (lst[i - 1].second == 0)q++;
			ma[sum] += q;
			sum++;
		}
		else
		{
			q = lst[i].first - lst[i - 1].first ;
			if (lst[i - 1].second == 0)q++;
			ma[sum] += q;
			sum--;
		}
	}
	for (int i = 1;i <= n;i++)
	{
		cout << ma[i] << " ";
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_Rikka_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值