lower_bound离散化写法

我一直以为我写过这篇博客了,直到后来。。。。

先介绍一下离散化

我没有系统的学过离散化,不过以我的理解就是将一个数值之间相差比较大的数组即类似max - 次max > 1的数组转化成max - 次max = 1的数组,也就是当数组中数的数值对算法影响不大,但是大小关系影响较大的时候,我们把他们的大小关系用相差1的数表示。
举个例子:
a数组: 99 55 68 47 100 2888888888
离散化后得b数组
b数组: 4 2 3 1 5 6
可以看出数值范围就小了许多但是对应下标的各项大小关系是不变的。

用到的函数

sort

排序函数,很常见的函数,作用是让a数组具有单调性,好用下一个函数

unique(去重)

顾名思义,不同,就是不同的留下,相同的消失,该函数会去掉数组中重复出现的数值,只留下第一次出现的数值。
x = u n i q u e ( a + 1 , a + n + 1 ) − a − 1 , x = unique(a + 1, a + n + 1)- a - 1, x=uniquea+1,a+n+1a1x为去重后a数组的长度。 关于大于x后面的数还有一些规则(我忘了qwq)
当然,unique需要在数组有序的情况下使用

lower_bound

这个就是这篇离散化最重要的函数的,他会返回查询数组中第一个大于等于查询数值的位置的迭代器或指针
比如一个a数组 x m = l o w e r b o u n d ( a + 1 , a + n + 1 , m ) − a xm = lower_bound(a + 1, a + n + 1, m) - a xm=lowerbound(a+1,a+n+1,m)a 此时xm的值就是a数组中第一个大于等于m的数的下标。

方法

需要两个数组, 这里用a, b两个数组,
还有两个变量,这里用n, x。
a数组是读入的原数组,b数组是离散化后的数组。
n记录的是需要读入的数组长度,x记录的是去重后数组的长度。

那么①:读入n, 读入a, 同时令b[i] = a[i];
②对a进行排序,使a有序 s o r t ( a + 1 , a + n + 1 ) sort(a + 1, a + n + 1) sort(a+1,a+n+1)
③对a去重,同时记录去重后长度 x = u n i q u e ( a + 1 , a + n + 1 ) − a − 1 x = unique(a + 1, a + n + 1) - a - 1 x=unique(a+1,a+n+1)a1
④使用lower_bound在长度为x的a数组中对b[i]进行查询, 并使b[i] = 查询出的下标
这一步需要详细说明:
a数组目前是被我们处理过的数组,长度为x且严格单调递增,并包含了所有在原数组中出现过的数值,
那么我们在用b数组查询时,第一个大于等于的b[i]的一定是b[i]本身,因为在b[i]数值出现之前a中没有大于b[i] 的数
同时a中数值在a中的下标能体现该数值在所有数值中的大小排名,所以就是离散化出的数值。

⑤使用b数组

代码

#include<bits/stdc++.h>

#define MAXN 1000010

using namespace std;

int a[MAXN], b[MAXN];
int x, y;
int n;

int main()
{
	scanf("%d", &n);
	
	for(int i = 1; i <= n; ++i){
		scanf("%d", &a[i]); b[i] = a[i];
	}
	
	sort(a + 1, a + n + 1);//排序
	
	x = unique(a + 1, a + n + 1) - a - 1;//去重并记录
	
	for(int i = 1; i <= n; ++i){
		b[i] = lower_bound(a + 1, a + x + 1, b[i]) - a; //查询并赋值
	}
	
	for(int i = 1; i <= n; ++i)//输出
		printf("%d ", b[i]);
	puts("");
	
	return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BIGBIGPPT

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

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

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

打赏作者

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

抵扣说明:

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

余额充值