牛客小白月赛22 H.货物种类(差分+区间变化+扫描)

题目链接:https://ac.nowcoder.com/acm/contest/4462/H
在这里插入图片描述这道题目我理解了做法之后,只想说出题人牛逼
题解为什么要去重,然后新排序;题解的真正意思;都值得去思考
(我感觉这道题目也没用多少差分数组呀,感觉就是样子像差分数组)
思路我都注释在代码里了

#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
	int l;
	int r;
	int d;
}a[110000];
int n,m;
int d;                  //记录种类数
int des[110000];        //记录种类
int res[110000];        //记录当前i种类的数目
vector<int> L[110000];  //记录在i点处开始的种类
vector<int> R[110000];  //记录在i点处结束的种类
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].d);
		des[++d]=a[i].d;
	}
	//因为种类数量范围为10^9,数组无法保存这么大的,所有要进行去重,然后重新从1编号
	//unique函数,返回去重后的最后一位的下一个坐标(覆盖式)
	sort(des+1,des+1+d);
	d=unique(des+1,des+1+d)-des-1;
	for(int i=1;i<=m;i++)
	{
		a[i].d=lower_bound(des+1,des+1+d,a[i].d)-des;
		L[a[i].l].push_back(a[i].d);
		R[a[i].r].push_back(a[i].d);
	}
	int ans=0,pos=0;        //记录最大种类数
	int now=0;              //记录当前种类数
	for(int i=1;i<=n;i++)
	{
		//下面for循环也可以写为 for(int j:L[i])   指遍历整个L[i]vector数组
		int len=L[i].size();
		for(int j=0;j<len;j++)
		{
			if(!res[L[i][j]])     //如果当前种类目前还没有,则种类数加一
				now++;
			res[L[i][j]]++;
		}
		if(now>ans)
		{
			ans=now;
			pos=i;
		}
		len=R[i].size();
		for(int j=0;j<len;j++)  //这一步对当前i无影响,是为了i++做准备的
		{
			res[R[i][j]]--;
			if(!res[R[i][j]])   //如果在i处结束时,某一种类的数量为0,那么总体种类数要减一
				now--;
		}
	}
	cout<<pos<<endl;
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Buyi.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值