離散化及兩種主要實現

2021-10-02 18:43:21 字數 2119 閱讀 7303

離散化

所謂離散化就是當我們需要存一定數量的陣列時,陣列開不了那麼大,但是數字的種數不多,故離散化就是改變了資料數量的相對大小

去重離散化

給定乙個包含大量重複元素陣列,而我們用到其中的每乙個數即可,去重顯然是更好的選擇

unique函式

標頭檔案:#include

注意:使用前一定要先將無序的列表排序,使重複的元素相鄰

原理:

舉例:int陣列a[7](排過序的):1,1,2,3,3,3,6

使用過unique(a,a+7),陣列變為1,2,3,6,3,3,6

(ps:unique只改變了前4(即不重複元素的個數)個數字,後邊的不變)

而且返回的就是上面標記數字的位址

因此常常用來求出不重複元素:

int a[n];

sort

(a,a+n)

;int num=

unique

(a,a+n)

-a;//按上面例子來看num就是4

for(

int i=

0;i) cout<<為什麼給它起名對映離散化呢,因為這種離散化不減少元素的個數,而且是採用給陣列每個數對映乙個id的方法間接得到我們需要的結果。例如乙個只有四個數的陣列a:

a[i] = 104,1e6,1e8,1e10

而如果我們給每個數乙個對映將a陣列轉化為b[i] = 1,2,3,4,我們可以發現陣列元素之間的相對大小關係是不影響的

還有如果我們要得到一堆資料中每個數i(i很大)作為陣列下標的值,而這些資料總數卻不太多。顯然直接開陣列是存不下的,因此就需要離散化,下面舉乙個很實用的例子

逆序對

對於乙個陣列a若 i > j && a[i] < a[j] 那麼稱a[i]與a[j]是乙個逆序對

其實逆序對就是求每個數前面有多少個比它大的數。暴力求解顯然超時,那麼我們這樣想,如果給定一組亂序數,求解每個數前面有多少比它小的,那麼可以用樹狀陣列。樹狀陣列就是可以很方便維護字首和,從而得到每個數前面有多少比它小的,但是我們如果用陣列存每個數作為下標,開不了很大的陣列怎麼辦?離散化!

究竟如何離散化,我們先給每個數按輸入順序分配乙個id,可以用結構體儲存,例如id1

234a[i]

-11925

那麼我們按a[i]從小到大排序可以得到id1

342a[i]-12

519那麼我們可以發現原始陣列的逆序對數是2,而按id來看得到的逆序對個數也為2。於是我們只要按id作為下標存到樹狀陣列中,我們每次查詢得到某個id前面有多少個比它小的,那麼id-getsum(a[i].id)就可以得到前面有多少個比它大的,但是這樣顯然太麻煩,我們如果直接把a[i]按id從大到小排序,查詢每個id前面都多少個比它大的不就行了?但是這時要注意先更新先查詢的區別,如果先更新的話,該節點本身以及之前的樹狀陣列對應值都會更新,因此要getsum(a[i].id-1)。但是如果先查詢再更新的話就直接getsum(a[i].id)即可

#include 

#include

using namespace std;

#define lowbit

(x)(x&

(-x)

)typedef long

long ll;

const

int maxn=

5e5+10;

struct nodea[maxn]

;int t[maxn]

;ll n;

bool cmp

(node &a,node &b)

void

update

(int i)

}ll getsum

(int i)

intmain()

sort

(a+1

,a+1

+n,cmp)

; ll ans=0;

for(

int i=

1;i<=n;i++

)printf

("%lld\n"

,ans)

;return0;

}

離散化 兩種離散化方式詳解

離散化,就是把一些很離散的點給重新分配。舉個例子,如果乙個座標軸很長 1e10 給你1e4個座標,詢問某乙個點,座標比它小的點有多少。很容易就知道,對於1e4個點,我們不必把他們在座標軸上的位置都表示出來,因為我們比較有多少比它小的話,只需要知道他們之間的相對大小就可以,而不是絕對大小,這,就需要離...

模板 離散化實現的兩種方式

第一種 利用結構體實現離散化 這種方法的弊端是無法辨別重複元素 例如 1 2 2 3 3 離散化之後是 1 2 3 4 5 使用時應注意 include using namespace std const int n 5e5 10 int n int b n struct node sort arr...

離散化的兩種操作

離散化是程式設計中乙個常用的技巧,它可以有效的降低時間複雜度。其基本思想就是在眾多可能的情況中,只考慮需要用的值。離散化可以改進乙個低效的演算法,甚至實現根本不可能實現的演算法。要掌握這個思想,必須從大量的題目中理解此方法的特點。有些資料本身很大,自身無法作為陣列的下標儲存對應的屬性。如果這時只是需...