線段樹只是acm眾多演算法中的很普遍的一種,但是他的效率非常高,一般演算法複雜度為o(n)的題,通過線段樹之後,就會變成o(log2(n)),本文是以杭電acm1166題舉例,來對線段樹進行一些了解:杭電1166原題鏈結
比如說求5到12的總人數,用線段樹的話,你只要找到【5,7】、【8,10】、【11,12】這三個部分,加起來就是所求的值。比5+6+7+···+11+12效率多了。
線段樹有三個函式,建樹、更新、查詢。
在開始之前需要定義乙個結構體,用來儲存線段樹節點的各種值
struct sts[
50000*4
];//這裡需要上限×4,防止溢位,
建樹的時候,需要用乙個陣列來儲存資料,用來以後訪問各個節點的資料。
訪問線段樹的方法:例如當前訪問的節點是【1,4】這個節點,用s[4]表示,那麼訪問左孩子節點的時候可以用s[2×4],即s[8];訪問右孩子節點的時候可以用s[2×4+1],即s[9]。
//建樹
/*傳入的引數:
l:左界限
r:右界限
k:剛開始的下標值
*/void
bulid
(int l,
int r,
int k)
int mid =
(l + r)/2
;bulid
(l, mid,
2* k)
;//建立k的左枝
bulid
(mid +
1, r,
2* k +1)
;//建立k的右枝
}
更新
/*
傳入的引數:
d:需要修改的值
n:增加的值(如果是減少,傳參的時候傳入負值就可以)
k:剛開始的下標值
*/void
insert
(int d,
int n,
int k)
int mid =
(s[k]
.l + s[k]
.r)/2;
//取中間點
if(d <= mid)
else
s[k]
.n = s[
2* k]
.n + s[
2* k +1]
.n;//每次使用更新函式的時候都需要更新每個節點上n的值
}
查詢
int ans;
//這裡需要乙個全域性變數,用來儲存答案。
/*傳入的引數:
l:查詢的左界
r:查詢的右界
k:剛開始的下標值
*/void
fin(
int l,
int r,
int k)
int mid;
mid =
(s[k]
.l + s[k]
.r)/2;
if(r <= mid)
else
if(l>mid)
else
}
# include
# include
# include
# include
using namespace std;
struct sts[
50000*4
];/*傳入的引數:
l:左界限
r:右界限
k:剛開始的下標值
*/void
bulid
(int l,
int r,
int k)
int mid =
(l + r)/2
;bulid
(l, mid,
2* k)
;//建立k的左枝
bulid
(mid +
1, r,
2* k +1)
;//建立k的右枝}/*
傳入的引數:
d:需要修改的值
n:增加的值(如果是減少,傳參的時候傳入負值就可以)
k:剛開始的下標值
*/void
insert
(int d,
int n,
int k)
int mid =
(s[k]
.l + s[k]
.r)/2;
//取中間點
if(d <= mid)
else
s[k]
.n = s[
2* k]
.n + s[
2* k +1]
.n;//每次使用更新函式的時候都需要更新每個節點上n的值
}int ans;
//這裡需要乙個全域性變數,用來儲存答案。
/*傳入的引數:
l:查詢的左界
r:查詢的右界
k:剛開始的下標值
*/void
fin(
int l,
int r,
int k)
int mid;
mid =
(s[k]
.l + s[k]
.r)/2;
if(r <= mid)
else
if(l>mid)
else
}int
main()
while(1
)scanf
("%d%d"
,&a,
&b);
if(str[0]
=='a'
)else
if(str[0]
=='s'
)else
if(str[0]
=='q')}
}return0;
}
寫在最後:輸入輸出的時候,一定要用scanf和printf,如果用cin和cout的時候,會超時的,我就是在這裡卡了很久:用cin的時候超時了(超過1000ms),用scanf只有300ms左右。以前根本沒想過cin會比scanf慢那麼多(輸入string字串的時候用的是cin,因為string會方便很多,也可以用char的字元陣列)。 線段樹單點更新hdu1166
學習自 先序建子樹,然後回溯建立父節點 更新時先遞迴更新子節點,然後再回溯更新父節點 回溯思想很重要 include using namespace std const int maxn 50005 int sum maxn 2 void build int l,int r,int rt void ...
HDU 1166 線段樹單點更新
c國的死對頭a國這段時間正在進行軍事演習,所以c國間諜頭子derek和他手下tidy又開始忙乎了。a國在海岸線沿直線布置了n個工兵營地,derek和tidy的任務就是要監視這些工兵營地的活動情況。由於採取了某種先進的監測手段,所以每個工兵營地的人數c國都掌握的一清二楚,每個工兵營地的人數都有可能發生...
杭電 1166 敵兵布陣 (線段樹)
c國的死對頭a國這段時間正在進行軍事演習,所以c國間諜頭子derek和他手下tidy又開始忙乎了。a國在海岸線沿直線布置了n個工兵營地,derek和tidy的任務就是要監視這些工兵營地的活動情況。由於採取了某種先進的監測手段,所以每個工兵營地的人數c國都掌握的一清二楚,每個工兵營地的人數都有可能發生...