主要的目的是記錄一哈二維線段樹,在此之前先簡單總結一下一維線段樹。
線段樹顧名思義,處理線段(或者稱為區間)的整體屬性的一種資料結構。
主要操作為-範圍更新與查詢,時間複雜度為logn級別的。
構建過程為:
這棵樹將所定範圍(區間)不斷進行二分,直至只包含乙個值作為葉節點。
其他的非葉節點表示線段經過二分過後的某個區間。
更新操作:
將所給的區間,與線段樹節點區間比較
所給區間包含樹節點區間,則處理。
區間與樹節點區間不相交,丟掉。
區間有交叉,遞迴到子節點,進行相同步驟。
//有lazy標記優化
目的是當所給區間包含樹節點,不進行子節點的處理,但是做個標記(另開個陣列或者加個屬性),表示這些節點是要處理的,但是我們不進行處理,等到查詢的時候進行處理。
查詢操作:
類似有lazy標記的,則處理後續節點,清除lazy標記,給子節點標記上,逐層進行,如果到了最後一層則不用管lazy標記了。
基本上是樹套樹,適合矩陣查詢。時間複雜度是logn^2
基本上是在第一層線段樹的基礎上,每個節點的屬性是另乙個線段樹。
基本上更新是先按一維查詢,
三種情況中
找到包含的情況後(一維線段樹有講),進行第二維的更新。
下面的**是更新操作
const
int max_n=
1<<9;
//500個
#define thres 2*max_n
int n,data[
2*max_n][2
*max_n]
;//省遞迴引數
int yy1,yy2,vv;
void
changey
(int y1,
int y2,
int iy,
int l,
int r,
int ix)
else
if(y1<=l && y2>=r)};
push_down
(iy);}
else
}void
changex
(int x1,
int x2,
int ix,
int l,
int r)
else
if(x1<=l && x2>=r)};
push_down
(ix);/*
changey(yy1, yy2, 1, 0, 501,ix);
push_down_copy=[&push_down_copy](int ix)
else
}//init range 0 - 500
void
update
(int x1,
int x2,
int y1,
int y2,
int v)
查詢類似
int
queryx
(int x1,
int l,
int r,
int ix)
if(x1else
}int
queryy
(int y1,
int l,
int r,
int ix,
int iy)
int mid=l+r>>2;
if(y1else
}int
query
(int x1,
int y1,
int l,
int r)
面試總結 演算法篇
leetcode是經同學介紹的 據說有很大一部分演算法面試題都在leetcode的題庫中,甚至是完全一樣,既然想好要學點什麼就要一點點慢慢的啃吧。題目涉及別家 版權,就不在這裡說什麼了,本來還想每日一刷讓大家幫忙做個監督,估計不太合適了。為了更好的自己,加油!用了三天左右空餘時間,把sql簡單刷了一...
面試總結 演算法相關
設定雙指標,間距為k,順序後移,當right至末尾,left指向倒數第k個元素。使用快慢指標的方法,一定步數後,兩個指標會相遇。思路,建乙個棧存放單鏈表的偶數字。採用歸併方法,合併兩個有序集合。棧 單鏈表奇數字 設定兩個陣列,第乙個陣列a1放置26個字母。a1 a b z 第二個陣列a2放置a1的個...
LeetCode習題總結 演算法(5)
首先先上原題 通過給定對應七種羅馬數字對應的七種字元 i,v,x,l,c,d 和 m 以及對應七種字元所對應的數值 i 1,v 5,x 10,l 50,c 100,d 500,m 1000。去求解在給定乙個羅馬字串時,對應的羅馬數字表示為多少。思路 基於此題目,我們可以發現對應的羅馬字元和羅馬數字之...