點更新:
1 #include //view code點更新2 #include 3 #include 4
5using
namespace
std;67
const
int n=10000;8
intn,m,a[n];
9struct
node
10tree[4*n];
1415
void build(int id,int l,int r);//
建一棵線段樹
16int query_sum(int id,int l,int r);//
查詢區間和
17int query_max(int id,int l,int r);//
查詢區間最大值
18void update(int id,int pos,int val);//
更新位置pos的值增加val
1920
intmain()
2137
return0;
38}39void build(int id,int l,int
r)40
48else
4956}57
int query_sum(int id,int l,int
r)5869}
70int query_max(int id,int l,int
r)7182}
83void update(int id,int pos,int
val)
8490
else
9198 }
區間更新:
1 #include 2 #include 3 #include 4view code5using
namespace
std;67
const
int n=100005;8
intn,m,a[n];
9struct
node
10tree[4*n];
1415
void build(int id,int l,int r);//
建一棵線段樹
16long
long query_sum(int id,int l,int r);//
查詢區間和
17void update(int id,int p1,int p2,int val);//
更新區間[p1,p2]的值增加val
1819
intmain()
2036
else
37 printf("
%lld\n
",query_sum(1
,t1,t2));38}
39return0;
40}41void build(int id,int l,int
r)42
50else
5157}58
long
long query_sum(int id,int l,int
r)59
71if(r<=mid) return query_sum(2*id,l,r);
72else
if(l>mid) return query_sum(2*id+1
,l,r);
73else
74return query_sum(2*id,l,mid)+query_sum(2*id+1,mid+1
,r);75}
76}77void update(int id,int p1,int p2,int
val)
7884
else
8593
if(p2<=mid)
94 update(2*id,p1,p2,val);
95else
if(p1>mid)
96 update(2*id+1
,p1,p2,val);
97else
98102 tree[id].sum_=tree[2*id].sum_+tree[2*id+1
].sum_;
103}
104 }
需要注意的是:線段樹空間應開為原陣列長度的4倍。
空間複雜度~o(n*4),每次更新和查詢操作的複雜度都是o(logn)。
線段樹基本操作(1)
建樹,查詢和單點修改 把一段長度為2 k的區間逐次對半分,可以總共分成2 k 1 1各節點,變成了一棵二叉樹 對於區間 lt,rt 它的子節點為區間 lt,mid 和區間 mid 1,rt 查詢時只要要查詢的區間的左右邊界剛好等於已知區間的邊界,就可以返回值了,不需要一搜到底 對於單點修改,基本上和...
線段樹基本操作(2)
假如指定乙個操作給一段區間的所有值加2,求任意區間的最小值 更新 才發現在change是就更改結點值而查詢時只釋放結點會更快,下面摘自網上 對於任意區間的修改,我們先按照查詢的方式將其劃分成線段樹中的結點,然後修改這些結點的資訊,並給這些結點標上代表這種修改操作的標記。在修改和查詢的時候,如果我們到...
線段樹及其基本操作
處理何種問題 陣列單點更新,單點查詢,區間更新,區間求和,區間求最值。效能 時間複雜度為o logn 原理 區間跟新的懶惰標記了解一下,其餘略 實現步驟 略 線段樹的區間求最值差別不大,在此貼乙份a過題的最值 用來對比找bug。include include include includeusing...