至於為什麼陣列要開4倍(能用就行)struct node
;ll a[maxn]
;node tr[maxn<<2]
;
}以及區間查詢
單點維護ll query
(int x,
int l,
int r)
///interval sum
if(tr[x]
.tag!=0)
///下推lazy_tag(區間更新時使用)
int mid=tr[x]
.l+tr[x]
.r>>1;
if(l>mid)
return
query
(x<<1|
1,l,r)
;else
if(r<=mid)
return
query
(x<<
1,l,r)
;else
return
query
(x<<
1,l,mid)
+query
(x<<1|
1,mid+
1,r)
;}
區間維護void
update
(int x/*查詢x號元素*/
,int y ,
int node )
///單點更新,將x號元素值更新為y
int mid=tr[node]
.l+tr[node]
.y>>1;
if(x<=mid)
update
(x,y,node<<1)
;else
update
(x,y,node<<1|
1); tree[node]
.sum=tr[node<<1]
.sum+tr[node<<1|
1].sum;
}
不同於單點維護,因為區間維護需要操作的是區間內所有節點,每次都更新的話效率較低,所以需要建立乙個lazytag,用來先儲存區間的操作,等到查詢的時候再並到線段樹里
即:如果某個區間內所有點都被增加了相同的值,則在lazytag中做上標記(以及add的值)
在後續訪問到有lazytag的節點時,不用下推lazytag,如果要訪問該節點的子節點,僅需要下推到兩個子節點struct node
;ll a[maxn]
;node tr[maxn<<2]
;
以及區間更新函式void
push_down
(int x)
envoid
itvupdate
(int x,ll num,
int l,
int r)
///interval update
if(tr[x]
.tag!=0)
push_down
(x);
int mid=tr[x]
.l+tr[x]
.r>>1;
if(l>mid)
itvupdate
(x<<1|
1,num,l,r)
;else
if(r<=mid)
itvupdate
(x<<
1,num,l,r)
;else
tr[x]
.sum=tr[x<<1]
.sum+tr[x<<1|
1].sum;
}
bzoj4636 蒟蒻的數列 線段樹
蒟蒻的數列 bzoj 4636 題目大意 給定乙個序列,初始均為0。n次操作 每次講一段區間中小於k的數都變成k。操作的最後詢問全域性和。注釋 1 le n le 4 cdot 10 4 想法 那個操作就是乙個不好好說話的操作,說白了就是對區間的每乙個數取max 然後我們對於那個序列建立分治線段樹。...
bzoj4636 蒟蒻的數列 離散化 線段樹
題目描述 蒟蒻dcrusher不僅喜歡玩撲克,還喜歡研究數列 題目描述 dcrusher有乙個數列,初始值均為0,他進行n次操作,每次將數列 a,b 這個區間中所有比k小的數改為k,他想知道n次操作後數列中所有元素的和。他還要玩其他遊戲,所以這個問題留給你解決。輸入第一行乙個整數n,然後有n行,每行...
最小生成樹(蒟蒻)
模板 修建道路 題面 farmer john最近得到了一些新的農場,他想新修一些道路使得他的所有農場可以經過原有的或是新修的道路互達 也就是說,從任乙個農場都可以經過一些首尾相連道路到達剩下的所有農場 有些農場之間原本就有道路相連。所有n 1 n 1,000 個農場 用1.n順次編號 在地圖上都表示...