線段樹需要的空間。
區間為1-->n
假設是一棵完全二叉樹,且樹高為i。
完全二叉樹性質:第i層最多有2^(i-1)個結點。
那麼 2^(i-1) = n; i = log2(n) + 1;
共有 2^i - 1 個結點, 即 2^(log2(n) + 1) - 1個結點
即2 * 2^log2(n) - 1 = 2 * n - 1
但這是建立樹是完全二叉樹的情況下。
但是如圖所示,樹可能不是完全二叉樹,最下面一層的結點個數》n, 我們以2n來來計算,那麼就需要4*n-1的空間。
單點更新
1 #include 2 #includeview code3const
int n = 50000;4
int a[n*4
],ans;
5void swap(int &a, int &b)611
void build(int rt, int l, int
r)12
18int mid = (l + r) >> 1
;19 build(rt<<1
,l,mid);
20 build(rt<<1|1,mid+1
,r);
21 a[rt] = a[rt<<1] + a[rt<<1|1
];22}23
24void query(int rt, int l, int r, int l, int
r)25
31int mid = (l + r) >> 1;32
if(r<=mid)
33 query(rt<<1
,l,r,l,mid);
34else
if(l>mid)
35 query(rt<<1|1,l,r,mid+1
,r);
36else
3741}42
void update(int rt, int val, int pos, int l, int
r)43
49int mid = (l + r) >> 1;50
if(pos <=mid)
51 update(rt<<1
,val,pos,l,mid);
52else
53 update(rt<<1|1,val,pos,mid+1
,r);
54 a[rt] = a[rt<<1] + a[rt<<1|1
];55}56
intmain()
5781
else
if(str[0]=='a'
)8285else
86 update(1,-j,i,1
,n);87}
88}89return0;
90 }
成段更新, 要用到懶惰標記,每次更改區間時,不會更新到葉子結點,而是標記,等有需要了才去更新
1 #include 2 #includeview code3const
int n = 100000 + 10;4
struct
node
5a[n*8];9
void pushup(int
rt)10
13void pushdown(int rt, int
m)1422}
23void build(int rt, int l, int
r)24
31int mid = (l + r) >> 1
;32 build(rt<<1
,l,mid);
33 build(rt<<1|1,mid+1
,r);
34pushup(rt);35}
36void update(int rt, int l, int r, int val, int l, int
r)37
44 pushdown(rt,r-l+1
);45
int mid = (l + r) >> 1;46
if(l<=mid) update(rt<<1
,l,r,val,l,mid);
47if(r>mid) update(rt<<1|1,l,r,val,mid+1
,r);
48pushup(rt);49}
5051
52int
main()
5366 printf("
case %d: the total value of the hook is %d.\n
",tcase,a[1
].sum);67}
68return0;
69 }
線段樹成段更新之延遲更新
成段更新的重點是延遲更新,以區間 1,3 為例說明。注意,此例中 更新 為修改元素的值為a,查詢 為求區間中所有元素之和。建立二叉樹如圖示 每乙個圓圈代表乙個結點,圓內數字分別為結點標號和所對應區間,i 表示只含乙個數,只出現在葉節點中。當 要更新區間 1,2 中所有元素時,對應上圖即要更新結點4,...
線段樹成段更新 MB
include include using namespace std struct node a 4 1100000 int dp 1100000 n,m long long max long long int x,long long int y void build int l,int r,in...
Just a Hook(線段樹,成段更新)
題目傳送門 just a hook t組資料 每組有乙個長度為n的序列,給你m次操作,每次操作給你x,y,z三個數,操作 將x到y的數字變為z m次操作完成後求序列的總和 很明顯的線段樹題目,維護區間和即可 注意一下更新區間的方法即可 對於修改不能直接更新到底部,要成段更新 include usin...