線段樹(單點更新and成段更新)

2022-08-24 21:21:11 字數 2519 閱讀 3703

線段樹需要的空間。  

區間為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 #include 

3const

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 }

view code

成段更新, 要用到懶惰標記,每次更改區間時,不會更新到葉子結點,而是標記,等有需要了才去更新

1 #include 2 #include 

3const

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 }

view code

線段樹成段更新之延遲更新

成段更新的重點是延遲更新,以區間 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...