線段樹模板及總結
焦作一中資訊學 oy
在資訊學競賽中,經常遇到這樣一類問題:這類問題通常可以建模成數軸上的問題或是數列的問題,具體的操作一般是每次對數軸上的乙個區間或是數列中的連續若干個數進行一種相同的處理。常規的做法一般依託於線性表這種資料結構,導致了處理只能針對各個元素逐個進行,因此演算法的效率較低。
線段樹是一種能夠有效處理區間操作的高階資料結構,利用這種資料結構,我們能夠設計出針對上述問題更加高效的演算法。
線段樹的題目通常比較明顯,一般乙個很明顯的特徵是m次對某一區間長度的查詢。或者是修改。所以我們通常需要的只是將線段樹的模型稍加修改,進而套入題目中即可。
模板:對單個點的修改,和對一段區間的查詢:
線段樹單個點修改&區間查詢
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #include11 #include12 #include對一段區間的修改和查詢:13 #include14
using
namespace
std;
1516
const
int e=100006;17
struct
qq18
tree[4*e];//
線段樹要開4倍的點的個數
21int
n,t,a,b;
2223
void updata(int l,int r,int
root)
2431
32int mid=(l+r)/2
; 33 updata(l,mid,root*2
);34 updata(mid+1,r,root*2+1
);35 tree[root].maxx=max(tree[root*2].maxx,tree[root*2+1
].maxx);36}
3738
39int search(int l,int r,int
root)
4048
49int
main()
5063
64fclose(stdin); fclose(stdout);
65return0;
66 }
線段樹 區間 修改&查詢
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #include11 #include12 #include以下是做線段樹題目時的易錯點:13 #include14
using
namespace
std;
1516
const
int e=100006;17
struct
qq18
tree[4*e];//
線段樹要開4倍的點的個數
21int
n,t,a,b;
2223
void updata(int l,int r,int root)//
更新資料
2433
34int mid=(l+r)/2,delta=tree[root].delta;
35 tree[root*2].maxx+=delta; tree[root*2].delta+=delta;
36 tree[root*2+1].maxx+=delta; tree[root*2+1].delta+=delta;
37 tree[root].delta=0;//
這句很關鍵,根的偏移量傳遞到子樹後清零
38 updata(l,mid,root*2
);39 updata(mid+1,r,root*2+1
);40 tree[root].maxx=max( tree[root*2].maxx, tree[root*2+1
].maxx);
41return;42
}4344int search(int l,int r,int
root)
4556
57int
main()
5871
72fclose(stdin); fclose(stdout);
73return0;
74 }
1、開線段樹的結構體時一定要開到4倍的點的大小;
2、寫區間求和時的題目時search()函式的返回值在不再區間裡時返回0,而區間求最小值時返回999999999,最大值時返回-999999999;(int時)一定要是九個9,不然有些極限資料會卡範圍;
3、寫修改單個點的值和乙個區間的值的函式最好分開,乙個是節省時間,還有可以防止**混亂而出錯;
4、search()&updata()函式中判斷區間範圍的if語句中l,r和查詢的區間a,b的關係容易出錯;
5、注意根節點和子節點的關係,特別是+1的問題,歸結為一句話就是:若加都加,若不加都不加即:
mid=(l+r);
左子樹:l~mid(不加一),根為root*2;
右子樹:r~mid+1(加一了),根為root*2+1(也加一);
6、權值是在邊上還是點上,這兩種關係**判斷上有不同;
7、結構體賦初值的時候也要注意,根據所求的是最大還是最小還是和來判斷;
8、線段樹的左端點在陣列中的下標一定要是1,而不是0。
以後如果發現問題,還會繼續補充......
線段樹總結
線段樹總結 線段樹的原理就是每乙個區間都可以被分成若干個不相交連續區間 重要 線段樹維護的資料 1.自身結構的資料 比如 左兒子 右兒子的編號 2.懶惰標記 整段區間都變成乙個值 或者將要進行什麼操作 根據每次操作的型別 把操作的區間分成若干個不連續的區間 然後把操作的標記賦值給相應的區間 3.答案...
線段樹總結
線段樹的入門級 總結 線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中的每乙個非葉子節點 a,b 它的左兒子表示的區間為 a,a b 2 右兒子表示的區間為 a b 2 1,b 因此線段樹是平衡二叉樹,最後的子節點數目為n,即整...
線段樹總結
解決的題目 對區間所對應的一些資料進行修改,查詢。基本步驟 先建樹,然後插入資料,然後更新,查詢。關鍵部分 用線段樹解題,關鍵是要想清楚每個節點要存哪些資訊以及這些資訊如何高效更新,維護,查詢。不要一更新就更新到葉子節點,那樣更新效率最壞就可能變成o n 的了。建樹的方式 1 陣列 若根節點下標為0...