改為求區間的最大值#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define fast ios::sync_with_stdio(false)
#define ll long long
#pragma gcc optimize(2)
using
namespace std;
const
int n =
2e5+10;
int tree[n]
;void
build_tree
(int arr,
int tree,
int node,
int start,
int end)
// 建立樹的操作 (node是當前tree陣列中的下標,start和end是node節點存放的arr陣列中的該範圍的左右界)
int mid =
(start + end)/2
;// 劈分陣列 (取當前arr範圍的一半向下取整)
build_tree
(arr,tree,
2* node +
1,start,mid)
;build_tree
(arr,tree,
2* node +
2,mid +
1,end)
;// 到這裡tree中node節點的左右子樹都已經建立好了,node節點的值就等於其左右子樹的節點之和
tree[node]
= tree[
2* node +1]
+ tree[
2* node +2]
;}void
update_node
(int arr,
int tree,
int node,
int start,
int end,
int idx,
int val)
// 修改線段樹中某個節點的操作 (o(log(n)))
int mid =
(start + end)/2
;if(idx >= start && idx <= mid)
else
tree[node]
= tree[
2* node +1]
+ tree[
2* node +2]
;// 當前樹階段的左右子樹都已經修改好了,重新計算當前根節點的值
}int
seek_tree
(int arr,
int tree,
int node,
int start,
int end,
int l,
int r)
// 求區間和的操作
intmain
(void);
int size =6;
int tree[n]=;
build_tree
(arr,tree,0,
0,size -1)
;//檢查樹的建立情況
for(
int i =
0; i <
15; i++
) cout << tree[i]
<<
" ";
cout << endl;
update_node
(arr,tree,0,
0,size -1,
4,6)
;for
(int i =
0; i <
15; i++
) cout << tree[i]
<<
" ";
cout << endl;
// 輸出通過線段樹計算得來的arr陣列中下標2到下標5範圍的元素和
cout <<
seek_tree
(arr,tree,0,
0,size -1,
2,5)
<< endl;
return0;
}
void
build_tree
(int arr,
int tree,
int node,
int start,
int end)
int mid =
(start + end)/2
;build_tree
(arr,tree,
2* node +
1,start,mid)
;build_tree
(arr,tree,
2* node +
2,mid +
1,end);
tree[node]
=max
(tree[
2* node +1]
, tree[
2* node +2]
);}void
update_node
(int arr,
int tree,
int node,
int start,
int end,
int idx,
int val)
int mid =
(start + end)/2
;if(idx >= start && idx <= mid)
else
tree[node]
=max
(tree[
2* node +1]
, tree[
2* node +2]
);}int
seek_tree
(int arr,
int tree,
int node,
int start,
int end,
int l,
int r)
// 求區間和的操作
else
if(start >= l && end <= r)
int mid =
(start + end)/2
;int left_max =
seek_tree
(arr,tree,node *2+
1,start,mid,l,r)
;int right_max =
seek_tree
(arr,tree,node *2+
2,mid +
1,end,l,r)
;return
max(left_max , right_max)
;}
線段樹 離散區間,單點維護區間
這道題當時用線段樹搞不行,用主席樹搞,也不行。當場自閉。其實當時想到離散,但是沒想到用單點維護線段樹的區間。你這樣想,無非就是2e6次詢問,最多1 e9被分成最多2e6區間,我們要求的位置,一定在這2e6點的右邊第乙個。那麼把這個點,以及這個點x以及x 1的點儲存下來。維護的時候,線段樹初始化所有的...
線段樹 離散區間,單點維護區間
這道題當時用線段樹搞不行,用主席樹搞,也不行。當場自閉。其實當時想到離散,但是沒想到用單點維護線段樹的區間。你這樣想,無非就是2e6次詢問,最多1 e9被分成最多2e6區間,我們要求的位置,一定在這2e6點的右邊第乙個。那麼把這個點,以及這個點x以及x 1的點儲存下來。維護的時候,線段樹初始化所有的...
線段樹(單點操作)
單點操作 元素 struct node tr maxn 2 節點型別 建樹 void pushup int m void build int m,int l,int r 直接結束 int mid l r 1 求中間值 build m 1,l,mid 左半邊 m 2 build m 1 1,mid 1...