1. 程式人生 > >ONE MORE TRY

ONE MORE TRY

先說兩個函式

unique函式:

去重函式

使用方法:unique (首地址,尾地址);

功能:去除相鄰的重複元素(只保留一個),並把重複的元素放在最後;
unique 是返回去重後的尾地址;


lower_bound() 函式
,在前閉後開區間進行二分查詢
lower_bound() 是返回>=val 的位置,當所有元素都小於val,返回last位置;
使用方法:lower_bound(首地址,尾地址,待查詢元素val);

一般情況下,我們離散化的話就是開一個結構體:

struct asd{
    int val;        //存入值
    int id;         //存入位置
};
asd q[N];

然後按照val從小到大排序一下;

然後取一下就好了;

for(int i=1;i<=n;i++)
    arr[q[i].id]=i;

但是這樣有一個點就是,如果是重複元素呢?

比如1  2 3 3 4

按照這樣離散化以後就會變成:1 2 3 4 5

然而我們可能有時候會需要重複元素離散化後的值是一樣的,比如上述結果我是需要:1 2 3 3 4

下面介紹一個這個離散化:

先將輸入元素存好,並再開一個vector(就叫xs吧)存入,然後將這個xs排序一下,然後利用unique函式去重,最後for一遍,每次利用Lower_bound()查詢到>=arr[i]的位置,

複雜度O(nlogn);

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+10;
int n;
int arr[N];
vector<int>xs;
void print()
{
    for(int i=1;i<=n;i++)
        printf("%d ",arr[i]);
    puts("");
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&arr[i]);
        xs.push_back(arr[i]);
    }
    
    sort(xs.begin(),xs.end());
    auto e=unique(xs.begin(),xs.end());
    
    for(int i=1;i<=n;i++)
        arr[i]=lower_bound(xs.begin(),e,arr[i])-xs.begin()+1;
    print();
    return 0;
}