雖然看著挺長,但是其中有很多注釋,同時也可作為洛谷p3372的題解。
從第10行看即可。
/// @file 線段樹模板
/// 預設下標從0開始, @see startat
// 如果很閒,可以包裝成模板類打發時間
#include
#if __cplusplus < 201103l
typedef
unsigned
long
uint32_t
;#endif
typedef
long
long ll;
const
int startat =1;
const
int n =
100001
;int
*val;
// values
struct
/* 不知道取啥名 */
a[n*4]
;/** @brief 構建線段樹
* @note 使用方法:build(1,n), 其中n表示陣列val的長度
*/void
build
(const
int l,
const
int r,
const
uint32_t i=startat)
// i: 當前點編號,下同
int mid =
(l + r)
>>1;
build
(l, mid, i<<1)
;build
(mid+
1, r, i<<1|
1); a[i]
.sum = a[i<<1]
.sum + a[i<<1|
1].sum;
}/**
* @warning 在修改和查詢時,只要進入子節點,就一定要`down`
*/inline
void
down
(const
uint32_t i)
}inline
voidup(
const
uint32_t i)
/** @brief 單點修改
* @param index 修改的位置
* @param v 變化量
*/void
update
(const
int index,
const ll v,
const
uint32_t i=startat)
down
(i);
int mid =
(a[i]
.l + a[i]
.r)>>1;
if(index<=mid)
update
(index, v, i<<1)
;else
update
(index, v, i<<1|
1);up
(i);
}/** @brief 區間修改
* @param l 左端點(起始位置)
* @param r 右端點(終止位置)
* @param add 變化量
* @warning 呼叫此函式時,「可選引數」i不能省略;
* 若省略,會匹配三參的單點修改update。
*/void
updata
(const
int l,
const
int r,
const ll add,
const
uint32_t i=startat)
down
(i);
int mid =
(a[i]
.l + a[i]
.r)>>1;
if(mid >= r)
updata
(l, r, add, i<<1)
;else
if(mid < l)
updata
(l, r, add, i<<1|
1);else
updata
(l, mid, add, i<<1)
,updata
(mid+
1, r, add, i<<1|
1);up
(i);
}/** @brief 區間查詢
* @param l 所查詢區間的左端點
* @param r 所查詢區間的右端點
*/ll query
(const
int l,
const
int r,
const
uint32_t i=startat)
intmain()
else
}}
ACM 資料結構 線段樹模板
include include using namespace std define maxn 200005 class nodenode maxn int getright int n void build int l,int r,int num node num l l node num r r...
模板 線段樹 資料結構 線段樹練習題三
給定一條長度為m的線段,有n個操作,每個操作有3個數字x,y,z表示把區間 x,y 染成顏色z,詢問染完色之後,這條長度為m的線段一共有幾種顏色。規定 線段的顏色可以相同。連續的相同顏色被視作一段。問x軸被分成多少段。乙個n,乙個l,n行x1,x2,color 被分成多少段 4 2010191 29...
資料結構 線段樹
啦啦啦啦啦啦線段樹是個好東西 好吧並沒有什麼好的 但貌似還是很好啊 線段樹就是一棵樹!顧名思義 又是這個詞 就是求關於一段的某些什麼什麼東西。比如區間最大值啊什麼的。引用百科知識 線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中...