离散化

数据的离散化

有些数据本身很大, 自身无法作为数组的下标保存对应的属性。如果这时只是需要这堆数据的相对属性, 那么可以对其进行离散化处理。当数据只与它们之间的相对大小有关,而与具体是多少无关时,可以进行离散化。

例如:

91054与52143的逆序对个数相同。

设有4个数:

1234567、123456789、12345678、123456

排序:123456<1234567<12345678<123456789

=>1<2<3<4

那么这4个数可以表示成:2、4、3、1

那么如何实现呢,思想是:先排序,再删除重复元素,最后就是索引元素离散化后对应的值。

	int total = 0;
        for (int i = 1; i <= n; ++i) {
		tmp[++tot] = e[i];
	}
	sort(tmp + 1, tmp + 1 + tot);
	int len = unique(tmp + 1, tmp + 1 + tot) - tmp - 1;//去重后元素个数 
	for (int i = 1; i <= n; ++i) {
		e[i].l = lower_bound(tmp + 1, tmp + 1 + len, e[i].l) - tmp;//重新赋值下标 
		e[i].r = lower_bound(tmp + 1, tmp + 1 + len, e[i].r) - tmp;
	}

这里有unique的用法 -> unique用法

下面我们来看一道离散化思想的题:火烧赤壁

坐标的离散

显然我们不能用数组去记录左右端点,就用结构体,之后就要就行离散操作了,对左端点进行排序,对下一条线段会有三种情况,我们只需要特判一下就好了,这里的中心思想就是:我们不需要开他们端点那么大的数组,我们只需要知道他们的相对位置

,相对属性,这样就是以点为主体,将左右端点看作数值,这种思想就是离散。

下面上代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
using namespace std;
const int MAXN = 20007;
struct Line {
    int l, r;
} e[MAXN];
int cmp(Line a,Line b){
    return a.l < b.l;
}
int main() {
    int n;
    long long ans = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d%d", &e[i].l, &e[i].r);
    }
    sort(e+1, e + 1 + n,cmp);
    int begin,end = e[1].l;
    for(int i = 1; i <= n; i++){
        if(e[i].l >= end){
            begin = e[i].l;
            end = e[i].r;
            ans += end - begin;
        }
        else{
            if(e[i].r <= end){
                continue;
            }
            else{
                ans += e[i].r - end;
                end = e[i].r;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值