資料離散化 線段樹

2021-06-22 08:03:18 字數 1559 閱讀 7701

前言:遇到了乙個矩形面積堆疊的問題,想了很久。終於找到了方法。先做個小記,待到具體問題時再分析。

資料離散化

高大上的名字,其實就是對資料的一種處理,也可以採取陣列 或者 容器(map、vector。。。)之類的來儲存。

之前的ibm技術俱樂部主席競選 那道題其實就是很好的應用。

有些資料本身很大, 自身無法作為陣列的下標儲存對應的屬性。

如果這時只是需要這堆資料的相對屬性(例如大小關係), 那麼可以對其進行離散化處理。

核心是:當資料只與它們之間的相對大小有關,而與具體是多少無關時,可以進行離散化。

使用方法:先排序,再刪除重複元素,之後索引元素離散化後的值。

線段樹

線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。

對於線段樹中的每乙個非葉子節點[a,b],它的左兒子表示的區間為[a,(a+b)/2],右兒子表示的區間為[(a+b)/2+1,b]。因此線段樹是平衡二叉樹,最後的子節點數目為n,即整個線段區間的長度。

使用線段樹可以快速的查詢某乙個節點在若干條線段中出現的次數,時間複雜度為o(logn)。而未優化的空間複雜度為2n,因此有時需要離散化讓空間壓縮。

線段樹至少支援下列操作:

insert(t,x):將包含在區間 int 的元素 x 插入到樹t中;

delete(t,x):從線段樹 t 中刪除元素 x;

search(t,x):返回乙個指向樹 t 中元素 x 的指標。

利用線段樹可以方便的求多個圖形的面積和周長問題,甚至更複雜的問題。

//線段樹模板

struct line

;struct line a[100];

int sum;

//建立

void build(int s,int t,int n)

//插入

void insert(int s,int t,int step)//要插入的線段的左端點和右端點、以及當前線段樹中的某條線段

if (a[step].left==a[step].right)   return;//當前線段樹的線段沒有兒子,插入結束返回

int mid=(a[step].left+a[step].right)/2;

if (mid>=t)    insert(s,t,step*2);//如果中點在t的右邊,則應該插入到左兒子

else if (mid=t)

count(s,t,step*2);

else

if (mid下面來自某大牛解釋:

線段樹的定義

定義1 長度為1的線段稱為元線段。

定義2 一棵樹被成為線段樹,當且僅當這棵樹滿足如下條件:

(1)    該樹是一棵二叉樹。

(2)    樹中每乙個結點都對應一條線段[a,b]。

(3)    樹中結點是葉子結點當且僅當它所代表的線段是元線段。

(4)    樹中非葉子結點都有左右兩個子樹,做子樹樹根對應線段[a , (a + b ) / 2],右子樹樹根對應線段[( a + b ) / 2 , b]。

離散化 線段樹

題目 分析 每次1操作會往序列底加first個second,first 和 second 都是最大1e9的資料,每次2操作詢問序列中第first到第second個數的和 一開始就感覺有點像線段樹,輸入資料太大我們可以離線處理把資料離散化下,然後扔到線段樹上,維護兩個陣列 sum 區間數的值的和 nu...

紙帶 線段樹 離散化

題目大意 每次給一段區間染色,求最後整個區間有多少種顏色 分析 用膝蓋想也知道這題線段樹可以輕鬆水過,於是出題人靈機一動,挖了個深坑,每次給的區間是左開右閉的,但題目沒說,他給了你一張圖,你們可以感受一下 於是正解wa成0分我也是很絕望的。有一點要注意一下,離散化後有些區間會並在一起,原來中間的顏色...

線段樹 離散化 染色

這個題目太坑了,一直給報超時,然後調了一下午發現多開了乙個map。ac include include include include include include include includeusing namespace std define maxn 10000000 100 define...