日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

常用技巧 —— 离散化

發布時間:2025/3/17 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 常用技巧 —— 离散化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【概述】

離散化是數據結構中的一個常用技巧,其可以有效的降低時空復雜度,其基本思想就是在眾多可能的情況中,只去考慮需要用到的值,通過離散化,可以改進低效的算法,甚至實現根本不可能實現的算法。

對于一些數量較少,但數值較大或者可能出現負數這種難以處理的數據,自身無法作為數組的下標保存對應的屬性,如果這時只是需要這些數據的相對屬性, 那么可以對其進行重新賦值,即進行離散化處理。

簡單來說,對于 n 個數據,當 n 很小而每個數據 a[i] 的數據范圍很大時,就可以考慮離散化為更小的值,將他們重新賦值為 [1,n] 之間的數據,從而實現更多的算法。

例如:有 1E5 個數,每個數的大小不超過 1E9,要對這些數進行某些操作(并查集等),那么肯定不能直接開 1E9 大小的數組,但是 1E5 的范圍就完全沒問題,也就是說,當不需要這些數據具體是多少時,只需要知道他們的相對大小。

離散化分為兩種,一種是重復的元素離散化后數值仍相同,一種則是重復的元素離散化后數值不同。

【STL+二分實現離散化】

使用?STL+二分 實現離散化,重復的元素數值仍相同,其實質就是利用一個輔助數組將要離散的數據保存下來,然后進行排序去重,最后再用二分將離散數據的位置放回原數組。

注:

  • 去重并不是將數組中重復的元素刪除,而是將重復的元素放在數組末尾
  • 二分時,要注意二分的區間范圍一定是離散化后的區間

例如:對于數組 {6,8,4,9,5,6,7,4},在排序后得到 {4,4,5,6,6,7,8,9},去重后得到 {4,5,6,7,8,9},經過二分后,原序列變為 {3,5,1,6,2,3,4,1}

int temp[N],a[N]; int main(){int n;cin>>n;for(int i=1;i<=n;i++){cin>>a[i];temp[i]=a[i];//輔助數組臨時存儲}sort(temp+1,temp+n+1);//排序,便于去重int len=unique(temp+1,temp+n+1)-temp-1;//去重,len為去重后數組長度for(int i=1;i<=n;i++)//a[i]即為離散化后的數組a[i]=lower_bound(temp+1,temp+len+1,a[i])-temp; }

【用數組離散】

使用數組實現離散化,重復的元素數值不同,其直接用結構體存儲原序列元素的位置,經過排序后將他們重新賦值,最后將結果存放在 rank 數組中。

例如:

對于序列 {3,6,5,10,8},其初始值和 id 為:?

經過排序后:

進行離散化:

再按照原來的順序進行排列:

此時,rank 數組就是離散化后的值

struct Node{int val,id;bool operator < (const Node &rhs)const{//按值排序return val<rhs.val;} }a[N]; int rank[N];//離散化后的值 int main(){int n;cin>>n;for(int i=1;i<=n;i++){cin>>a[i].val;a[i].id=i;//記錄序號}sort(a+1,a+n+1);//按值排序for(int i=1;i<=n;i++)//進行映射rank[a[i].id]=i; }

【例題】

  • 程序自動分析(洛谷-P1955)(離散化+并查集):點擊這里
  • Making the Grade(POJ-3666)(離散化思想+線性DP):點擊這里
  • Mindis(HDU-6670)(離散化+網格圖建圖+bfs):點擊這里
  • Parity game(POJ-1733)(離散化+帶權并查集區間問題):點擊這里
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!

總結

以上是生活随笔為你收集整理的常用技巧 —— 离散化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。